1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#![no_std]

pub mod big_num;
mod naf;
mod ec_point;
mod ec_point_g;
mod ecj_point;

pub use ec_point_g::ECPointG;
pub use big_num::BigNum;

pub fn is_valid_secret(bytes: &[u8]) -> bool {
	if bytes.len() != 32 {
		return false;
	}

	let num = BigNum::from(bytes);

	!num.is_overflow() && num != 0
}

pub fn create_public_key(g: &ECPointG, secret: &[u8]) -> Option<[u8; 65]> {
	let mut num = BigNum::from(secret);

	if num.is_overflow() || num == 0 {
		return None;
	}

	Some(g.mul(&mut num).to_public_key())
}

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn create_public_key() {
		let secret: &[u8] = &[
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00,0x00,0x00,0x00,0x00,0x01,
		];

		let expected: &[u8] = &[
			0x04,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,
			0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,
			0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x48,0x3a,0xda,0x77,0x26,0xa3,
			0xc4,0x65,0x5d,0xa4,0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,
			0x48,0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,0xd4,0xb8
		];

		let g = ECPointG::new();

		let key = super::create_public_key(&g, secret).unwrap();

		assert_eq!(&key[..], expected);
	}

	#[test]
	fn create_public_key_empty_phrase() {
		let secret: &[u8] = &[
			0x4d,0x5d,0xb4,0x10,0x7d,0x23,0x7d,0xf6,0xa3,0xd5,0x8e,0xe5,0xf7,
			0x0a,0xe6,0x3d,0x73,0xd7,0x65,0x8d,0x40,0x26,0xf2,0xee,0xfd,0x2f,
			0x20,0x4c,0x81,0x68,0x2c,0xb7
		];

		let expected: &[u8] = &[
			0x04,0x3f,0xa8,0xc0,0x8c,0x65,0xa8,0x3f,0x6b,0x4e,0xa3,0xe0,0x4e,
			0x1c,0xc7,0x0c,0xbe,0x3c,0xd3,0x91,0x49,0x9e,0x3e,0x05,0xab,0x7d,
			0xed,0xf2,0x8a,0xff,0x9a,0xfc,0x53,0x82,0x00,0xff,0x93,0xe3,0xf2,
			0xb2,0xcb,0x50,0x29,0xf0,0x3c,0x7e,0xbe,0xe8,0x20,0xd6,0x3a,0x4c,
			0x5a,0x95,0x41,0xc8,0x3a,0xce,0xbe,0x29,0x3f,0x54,0xca,0xcf,0x0e
		];

		let g = ECPointG::new();

		let key = super::create_public_key(&g, secret).unwrap();

		assert_eq!(key.len(), expected.len());
		assert_eq!(&key[..], expected);
	}
}