1mod blake256;
2mod cnaes;
3mod hash_v2;
4mod hash_v4;
5mod slow_hash;
6mod util;
7
8use slow_hash::cn_slow_hash;
9
10pub fn cryptonight_hash_v0(buf: &[u8]) -> [u8; 32] {
12 cn_slow_hash(buf, slow_hash::Variant::V0, 0)
13}
14
15#[derive(thiserror::Error, Debug, Copy, Clone, Eq, PartialEq)]
16#[error("Data can't be hashed")]
17pub struct DataCanNotBeHashed;
18
19pub fn cryptonight_hash_v1(buf: &[u8]) -> Result<[u8; 32], DataCanNotBeHashed> {
23 if buf.len() < 43 {
24 return Err(DataCanNotBeHashed);
25 }
26
27 Ok(cn_slow_hash(buf, slow_hash::Variant::V1, 0))
28}
29
30pub fn cryptonight_hash_v2(buf: &[u8]) -> [u8; 32] {
32 cn_slow_hash(buf, slow_hash::Variant::V2, 0)
33}
34
35pub fn cryptonight_hash_r(buf: &[u8], height: u64) -> [u8; 32] {
37 cn_slow_hash(buf, slow_hash::Variant::R, height)
38}
39
40#[cfg(test)]
41mod tests {
42 use crate::*;
43
44 #[test]
45 fn slow_hash_0() {
46 fn test(inp: &str, exp: &str) {
47 let res = hex::encode(cryptonight_hash_v0(&hex::decode(inp).unwrap()));
48 assert_eq!(&res, exp);
49 }
50
51 test(
53 "6465206f6d6e69627573206475626974616e64756d",
54 "2f8e3df40bd11f9ac90c743ca8e32bb391da4fb98612aa3b6cdc639ee00b31f5",
55 );
56 test(
57 "6162756e64616e732063617574656c61206e6f6e206e6f636574",
58 "722fa8ccd594d40e4a41f3822734304c8d5eff7e1b528408e2229da38ba553c4",
59 );
60 test(
61 "63617665617420656d70746f72",
62 "bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87",
63 );
64 test(
65 "6578206e6968696c6f206e6968696c20666974",
66 "b1257de4efc5ce28c6b40ceb1c6c8f812a64634eb3e81c5220bee9b2b76a6f05",
67 );
68 }
69
70 #[test]
71 fn slow_hash_1() {
72 fn test(inp: &str, exp: &str) {
73 let res = hex::encode(cryptonight_hash_v1(&hex::decode(inp).unwrap()).unwrap());
74 assert_eq!(&res, exp);
75 }
76
77 test(
79 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
80 "b5a7f63abb94d07d1a6445c36c07c7e8327fe61b1647e391b4c7edae5de57a3d",
81 );
82 test(
83 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
84 "80563c40ed46575a9e44820d93ee095e2851aa22483fd67837118c6cd951ba61",
85 );
86 test(
87 "8519e039172b0d70e5ca7b3383d6b3167315a422747b73f019cf9528f0fde341fd0f2a63030ba6450525cf6de31837669af6f1df8131faf50aaab8d3a7405589",
88 "5bb40c5880cef2f739bdb6aaaf16161eaae55530e7b10d7ea996b751a299e949",
89 );
90 test(
91 "37a636d7dafdf259b7287eddca2f58099e98619d2f99bdb8969d7b14498102cc065201c8be90bd777323f449848b215d2977c92c4c1c2da36ab46b2e389689ed97c18fec08cd3b03235c5e4c62a37ad88c7b67932495a71090e85dd4020a9300",
92 "613e638505ba1fd05f428d5c9f8e08f8165614342dac419adc6a47dce257eb3e",
93 );
94 test(
95 "38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb",
96 "ed082e49dbd5bbe34a3726a0d1dad981146062b39d36d62c71eb1ed8ab49459b",
97 );
98 }
99
100 #[test]
101 fn slow_hash_2() {
102 fn test(inp: &str, exp: &str) {
103 let res = hex::encode(cryptonight_hash_v2(&hex::decode(inp).unwrap()));
104 assert_eq!(&res, exp);
105 }
106
107 test(
109 "5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374",
110 "353fdc068fd47b03c04b9431e005e00b68c2168a3cc7335c8b9b308156591a4f",
111 );
112 test(
113 "4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67",
114 "72f134fc50880c330fe65a2cb7896d59b2e708a0221c6a9da3f69b3a702d8682",
115 );
116 test(
117 "656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265",
118 "410919660ec540fc49d8695ff01f974226a2a28dbbac82949c12f541b9a62d2f",
119 );
120 test(
121 "657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c",
122 "4472fecfeb371e8b7942ce0378c0ba5e6d0c6361b669c587807365c787ae652d",
123 );
124 test(
125 "71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369",
126 "577568395203f1f1225f2982b637f7d5e61b47a0f546ba16d46020b471b74076",
127 );
128 test(
129 "757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465",
130 "f6fd7efe95a5c6c4bb46d9b429e3faf65b1ce439e116742d42b928e61de52385",
131 );
132 test(
133 "697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974",
134 "422f8cfe8060cf6c3d9fd66f68e3c9977adb683aea2788029308bbe9bc50d728",
135 );
136 test(
137 "657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e",
138 "512e62c8c8c833cfbd9d361442cb00d63c0a3fd8964cfd2fedc17c7c25ec2d4b",
139 );
140 test(
141 "4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c",
142 "12a794c1aa13d561c9c6111cee631ca9d0a321718d67d3416add9de1693ba41e",
143 );
144 test(
145 "73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e",
146 "2659ff95fc74b6215c1dc741e85b7a9710101b30620212f80eb59c3c55993f9d",
147 );
148 }
149
150 #[test]
151 fn slow_hash_r() {
152 fn test(inp: &str, exp: &str, height: u64) {
153 let res = hex::encode(cryptonight_hash_r(&hex::decode(inp).unwrap(), height));
154 assert_eq!(&res, exp);
155 }
156
157 test(
159 "5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374",
160 "f759588ad57e758467295443a9bd71490abff8e9dad1b95b6bf2f5d0d78387bc",
161 1806260,
162 );
163 test(
164 "4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67",
165 "5bb833deca2bdd7252a9ccd7b4ce0b6a4854515794b56c207262f7a5b9bdb566",
166 1806261,
167 );
168 test(
169 "656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265",
170 "1ee6728da60fbd8d7d55b2b1ade487a3cf52a2c3ac6f520db12c27d8921f6cab",
171 1806262,
172 );
173 test(
174 "657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c",
175 "6969fe2ddfb758438d48049f302fc2108a4fcc93e37669170e6db4b0b9b4c4cb",
176 1806263,
177 );
178 test(
179 "71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369",
180 "7f3048b4e90d0cbe7a57c0394f37338a01fae3adfdc0e5126d863a895eb04e02",
181 1806264,
182 );
183 test(
184 "757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465",
185 "1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef",
186 1806265,
187 );
188 test(
189 "757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465",
190 "1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef",
191 1806265,
192 );
193 test(
194 "697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974",
195 "c43cc6567436a86afbd6aa9eaa7c276e9806830334b614b2bee23cc76634f6fd",
196 1806266,
197 );
198 test(
199 "657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e",
200 "87be2479c0c4e8edfdfaa5603e93f4265b3f8224c1c5946feb424819d18990a4",
201 1806267,
202 );
203 test(
204 "4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c",
205 "dd9d6a6d8e47465cceac0877ef889b93e7eba979557e3935d7f86dce11b070f3",
206 1806268,
207 );
208 test(
209 "73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e",
210 "75c6f2ae49a20521de97285b431e717125847fb8935ed84a61e7f8d36a2c3d8e",
211 1806269,
212 );
213 }
214}