· 9 years ago · Sep 29, 2016, 01:50 AM
1/*
2chat.cpp
3
4What you type on one Arduino shows up in the screen
5attached to the other one and vice versa.
6*/
7#include <Arduino.h>
8
9/* Calculates and returns (a**b) mod m.
10Parameters:
11 a: base, nonnegative integer
12 b: exponent, nonnegative integer, a=b=0 not allowed
13 m: positive integer, m<2^16
14 Running time grows with log(b).
15*/
16uint32_t fast_pow_mod( uint32_t a, uint32_t b, uint32_t m ) {
17 uint32_t result = 1 % m;
18 uint32_t p = a % m;
19 for (int i=0; i<32; ++i) {
20// if ( b & (((uint32_t)1)<<i) !=0 )
21 if ( (b & (1ul<<i)) !=0 ) {
22 result = (result*p) % m;
23 }
24 p = (p*p) % m;
25 }
26 return result;
27}
28
29/* Calculates and returns (a**b) mod m.
30Parameters:
31 a: base, nonnegative integer
32 b: exponent, nonnegative integer, a=b=0 not allowed
33 m: positive integer, m<2^16
34 Running time grows linearly with b.
35*/
36uint32_t pow_mod( uint32_t a, uint32_t b, uint32_t m ) {
37 // Serial.println(a);
38 // Serial.println(b);
39 // Serial.println(m);
40 uint32_t result = 1 % m;
41 a = a % m;
42 uint32_t i;
43 for (i=0; i<b; ++i) {
44 result = (result*a) % m;
45 }
46 // Serial.println(i);
47 return result;
48}
49
50void test_pow_mod_case( uint32_t a, uint32_t b, uint32_t m, uint32_t expresult ) {
51 uint32_t result = fast_pow_mod( a, b, m );
52 Serial.print("Expected result: ");
53 Serial.println(expresult);
54 Serial.print("Computed result: ");
55 Serial.println(result);
56}
57
58/* Tests pow_mod */
59void test_pow_mod() {
60 test_pow_mod_case( 5, 10, 37, 30 );
61 test_pow_mod_case( 8, 10, 37, 11 );
62 // Edge cases! Small values and big values
63 //
64 test_pow_mod_case( 0, 10, 37, 0 );
65 test_pow_mod_case( 8, 0, 37, 1 );
66
67 test_pow_mod_case( 5, 20, 37, 12 );
68 test_pow_mod_case( 5, 200, 37, 12 );
69 test_pow_mod_case( 5, 2000, 37, 12 );
70 test_pow_mod_case( 5, 20000, 37, 12 );
71 test_pow_mod_case( 5, 200000, 37, 12 );
72 test_pow_mod_case( 5, 2000000, 37, 12 );
73 Serial.println("Testing done");
74}
75
76/* Receives a number from the PC and returns it as a uint32_t number */
77uint32_t get_input() {
78 // TODO: Fix me!
79 return 0;
80}
81
82int main() {
83 init();
84 Serial.begin(9600);
85 Serial3.begin(9600);
86 test_pow_mod();
87 while (true) {
88 }
89 uint32_t prime = 37;
90 uint32_t generator = 5;
91 uint32_t private_key = 10; // TODO: Fix this!!! generate this randomly
92 uint32_t public_key = pow_mod( generator, private_key, prime );
93 // key exchange:
94 Serial.print("Hey, here is the key you were looking for to share with your partner: ");
95 Serial.println(public_key);
96 Serial.print("Can you please enter the key received from your partner? ");
97 uint32_t partners_public_key = get_input();
98 uint32_t shared_secret = pow_mod( partners_public_key, private_key, prime );
99 char secret_key = shared_secret; // lowest 8 bits of the shared_secret
100
101 while (true) {
102 // PC keystroke -> other Arduino
103 if (Serial.available()>0) {
104 char c = Serial.read();
105 // Serial.write(c); // echo back to screen
106 Serial.print("ASCII code of character to be sent: ");
107 Serial.println((int)c);
108 // encrypt data:
109 c = c ^ secret_key;
110 Serial.print("Encrypted information being sent: ");
111 Serial.println((int)c);
112 Serial3.write(c); // sending byte to the "other" Arduino
113 }
114 // Other Arduino to PC screen
115 if (Serial3.available()>0) {
116 char c = Serial3.read();
117 // decrypt data:
118 c = c ^ secret_key;
119 Serial.write(c); // show byte on screen as character
120 }
121 }
122
123 Serial3.end();
124 Serial.end();
125 return 0;
126}