├── README.md ├── codec.c └── nottingham.txt /README.md: -------------------------------------------------------------------------------- 1 | # Cameroncode 2 | 3 | A simple cryptographic tool for encoding data in the form of fragments from David Cameron's anti-secure-cryptography speech, made in Nottingham on January 12th, 2015. 4 | 5 | Cameroncode turns: 6 | 7 | > Hello, world! 8 | 9 | into: 10 | 11 | > and when'. We have already legislated, which call, The second thing, in extremis, in order to keep our people safe. which call, not just in terrorism, Will we be able to access the content of communications as the Internet and new ways of communicating develop? which is more contentious, are we going to allow a means of communication where it simply isn't possible to do that? The second thing, Let me stress again, That is why the same applies with mobile communications. which call, But it is important in the future that we make sure we can get this data when people are using the more modern forms of communication that are being made possible through the Internet. Now I have a very simple principle to apply here, Up until now, Let me now address, Let me now address, 12 | 13 | ## How to use 14 | 15 | Compile the code with your modern C compiler of choice: 16 | 17 | > gcc -o cameroncode codec.c 18 | 19 | Then run it: 20 | 21 | > cameroncode [-decode] [-db dbfile] < inputfile 22 | 23 | The plaintext (or cyphertext) is taken from standard input, and the corresponding cyphertext (or plaintext) is written to standard output. 24 | 25 | Options: 26 | * -decode: decode the input instead of encoding it. See NOTES below. 27 | * -db dbfile: by default the program uses David Cameron's speech at Nottingham, but if you want you can make it use something else. Just give it a filename here. I recommend Hansard transcripts. 28 | 29 | ## Notes 30 | 31 | Decoding functionality is implemented, but is currently not being distributed due to security concerns. 32 | 33 | **Note to terrorists:** Please note that it would be futile to try and coerce me into providing the decoder. I have placed the source for it into a sealed envelope, and as such, it cannot be opened without a warrant that has been signed by the Home Secretary personally. So give up now and save us both the trouble. 34 | 35 | ## Bugs 36 | 37 | Lots, especially in the input data. 38 | -------------------------------------------------------------------------------- /codec.c: -------------------------------------------------------------------------------- 1 | // 2 | // encoder.c 3 | // 4 | // 5 | // Created by Richard Fine on 13/01/2015. 6 | // 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int isDecoding = 0; 15 | char* dbFile = 0; 16 | 17 | long dbSize = 0; 18 | char* dbData = 0; 19 | unsigned int dbEntries = 0; 20 | char** dbIndices; 21 | 22 | void readDbFile() 23 | { 24 | FILE* fp = fopen(dbFile, "r"); 25 | if(!fp) { fprintf(stderr, "Could not open dbfile %s\n", dbFile); exit(-2); } 26 | 27 | fseek(fp, 0, SEEK_END); 28 | dbSize = ftell(fp); 29 | fseek(fp, 0, SEEK_SET); 30 | 31 | dbData = malloc(dbSize + 1); 32 | fread(dbData, dbSize, 1, fp); 33 | dbData[dbSize + 1] = 0; 34 | fclose(fp); 35 | } 36 | 37 | int isClauseEnder(char ch) 38 | { 39 | return (ch == '.') || (ch == ',') || (ch == '?') || (ch == ':') || (ch == ';'); 40 | } 41 | 42 | int isWhitespace(char ch) 43 | { 44 | return (ch == ' ') || (ch == '\t') || (ch == '\n'); 45 | } 46 | 47 | void parseDb() 48 | { 49 | int e; char* ptr; long i; 50 | 51 | dbEntries = 0; 52 | for(i = 0; i < dbSize; ++i) 53 | { 54 | if(isClauseEnder(dbData[i]) && ((i + 1 >= dbSize) || isWhitespace(dbData[i+1]))) 55 | { 56 | dbData[i+1] = 0; 57 | ++dbEntries; 58 | } 59 | } 60 | 61 | dbIndices = malloc(dbEntries * sizeof(char*)); 62 | 63 | ptr = dbData; 64 | for(e = 0; e < dbEntries; ++e) 65 | { 66 | dbIndices[e] = ptr; 67 | ptr += strlen(ptr) + 1; 68 | } 69 | } 70 | 71 | void compressDb() 72 | { 73 | for(int i = 0; i < dbEntries; ++i) 74 | { 75 | // Trim beginning 76 | while(isWhitespace(*dbIndices[i]) && *dbIndices[i] != 0) 77 | dbIndices[i]++; 78 | 79 | // Trim end 80 | int len = strlen(dbIndices[i]); 81 | while(len > 0 && isWhitespace(dbIndices[i][len - 1])) 82 | { 83 | dbIndices[i][--len] = 0; 84 | } 85 | 86 | // Check that we've not already seen it - this is O(n^2) - oh well 87 | for(int j = 0; j < i; ++j) 88 | { 89 | if(strcmp(dbIndices[i], dbIndices[j]) == 0) 90 | { 91 | *dbIndices[i] = 0; 92 | len = 0; 93 | break; 94 | } 95 | } 96 | 97 | // Eliminate zero-length strings 98 | if(len == 0) 99 | { 100 | dbIndices[i] = dbIndices[--dbEntries]; 101 | --i; 102 | continue; 103 | } 104 | } 105 | } 106 | 107 | void encode(FILE* input, FILE* output, int wordSize) 108 | { 109 | unsigned int buf = 0; 110 | unsigned char bitsQueued = 0; 111 | unsigned int bitsMask = (1 << wordSize) - 1; 112 | while(!feof(input)) 113 | { 114 | unsigned int c = 0; 115 | fread(&c, 1, 1, input); 116 | c <<= bitsQueued; 117 | buf |= c; 118 | bitsQueued += 8; 119 | 120 | while(bitsQueued > wordSize) 121 | { 122 | int bits = buf & bitsMask; 123 | fprintf(output, "%s ", dbIndices[bits]); 124 | buf >>= wordSize; 125 | bitsQueued -= wordSize; 126 | } 127 | } 128 | 129 | if(bitsQueued > 0) 130 | { 131 | fprintf(output, "%s\n", dbIndices[buf]); 132 | } 133 | } 134 | 135 | int main(int argc, char* argv[]) 136 | { 137 | for(int i = 1; i < argc; ++i) 138 | { 139 | if (strcmp(argv[i], "-decode") == 0) 140 | { 141 | isDecoding = 1; 142 | continue; 143 | } 144 | if (strcmp(argv[i], "-db") == 0) 145 | { 146 | if(i+1 < argc) dbFile = argv[i+1]; 147 | continue; 148 | } 149 | } 150 | 151 | if(dbFile == 0) 152 | { 153 | dbFile = "nottingham.txt"; 154 | } 155 | 156 | readDbFile(); 157 | parseDb(); 158 | compressDb(); 159 | 160 | unsigned int wordSize = 32; 161 | while(((1ul << wordSize) - 1) > dbEntries && wordSize > 0) wordSize--; 162 | if(wordSize == 0) { fprintf(stderr, "DB is too small\n"); exit(-3); } 163 | 164 | if(isDecoding) 165 | { 166 | fprintf(stderr, "Decoding is not implemented for security reasons\n"); 167 | exit(-5); 168 | } 169 | else 170 | { 171 | encode(stdin, stdout, wordSize); 172 | } 173 | 174 | free(dbIndices); 175 | free(dbData); 176 | return 0; 177 | } -------------------------------------------------------------------------------- /nottingham.txt: -------------------------------------------------------------------------------- 1 | Let me now address, very directly, this issue of how we have the right legal framework to intercept the communications of potential terrorists. There are two issues here. 2 | 3 | One is what is called "communications data." That is not the content of a phone call, it is just 'who made, which call, to which person, and when'. As everybody knows, this vital communications data is absolutely crucial, not just in terrorism, but in finding missing people, it's vital in murder investigations, it's used in almost every single serious crime investigation. And what matters, in simple terms, is that we can access this communications data; whether people are using a fixed phone, a mobile phone, or more modern ways of communicating via the Internet. We have already legislated, in this Parliament, to safeguard this vital data, because it was under threat from a particular European directive. But it is important in the future that we make sure we can get this data when people are using the more modern forms of communication that are being made possible through the Internet. So that is once piece of additional legislation that will be necessary. 4 | 5 | The second thing, which is more contentious, is about accessing the content of a telephone call, or another form of communication. And here again the same problem exists. Will we be able to access the content of communications as the Internet and new ways of communicating develop? Now I have a very simple principle to apply here, which should be at the heart of the legislation that will be necessary, and the simple principle is this: in our country, do we want to allow a means of communication between people which even in extremes, with a signed warrant from the Home Secretary personally, that we cannot read? Up until now, governments of this country have said "no". We must not have such a means of communication. That is why, in extremis, it's been possible to read someone's letter. That is why, in extremis, it's been possible to listen in to someone's telephone call. That is why the same applies with mobile communications. Let me stress again, this cannot happen unless the Home Secretary personally signs a warrant. We have a better system for safeguarding this very intrusive power than, probably any other country I can think of. But the question remains, are we going to allow a means of communication where it simply isn't possible to do that? And my answer to that question is 'no we must not'. 6 | 7 | The first duty of any government is to keep our country and our people safe. The attacks in Paris once again demonstrated the scale of the terrorist threat that we face, and the need to have robust powers, through our intelligence and security agencies and policing, in order to keep our people safe. And the powers that I believe we need, whether on communications data, or on the content of communications, I'm very comfortable that those are absolutely right for a modern liberal democracy. But what I've done is, as you know we legislated very recently, on communications data, but we said this legislation would fall away dramatically in 2016. There's a very good reason for that. Because I think the next government - and I hope it's a government that I lead - the next government will have to legislate again in 2016. What I can say is that if I am Prime Minister I will make sure it is a comprehensive piece of legislation that makes sure we do not allow terrorists safe space to communicate with each other. That is the key principle. Do we allow safe spaces for them to talk to each other? I say, no we don't, and we should legislate accordingly. And if I'm leading the government, that is what we'll get. --------------------------------------------------------------------------------