Advertisement
Guest User

Untitled

a guest
Apr 25th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.52 KB | None | 0 0
  1. use std::slice::from_raw_parts;
  2. use std::mem::transmute;
  3.  
  4. const A_INIT: [u32; 12] = [
  5. 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191, 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C,
  6. 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A,
  7. ];
  8.  
  9. const B_INIT: [u32; 16] = [
  10. 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F, 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002,
  11. 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890, 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5,
  12. ];
  13.  
  14. const C_INIT: [u32; 16] = [
  15. 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55, 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433,
  16. 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F, 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60,
  17. ];
  18.  
  19. pub fn shabal256_fast(data: &[u8], term: &[u32; 16]) -> [u8; 32] {
  20. let mut a = A_INIT;
  21. let mut b = B_INIT;
  22. let mut c = C_INIT;
  23. let mut w_high = 0u32;
  24. let mut w_low = 1u32;
  25. let mut num = data.len() >> 6;
  26. let mut ptr = 0;
  27. let data_ptr = data.as_ptr() as *const u32;
  28. let data = unsafe { from_raw_parts(data_ptr, data.len() / 4) };
  29.  
  30. while num > 0 {
  31. input_block_add(&mut b, &data[ptr..]);
  32. xor_w(&mut a, w_low, w_high);
  33. apply_p(&mut a, &mut b, &c, &data[ptr..]);
  34. input_block_sub(&mut c, &data[ptr..]);
  35. swap_bc(&mut b, &mut c);
  36. incr_w(&mut w_low, &mut w_high);
  37. ptr = ptr.wrapping_add(16);
  38. num = num.wrapping_sub(1);
  39. }
  40. input_block_add(&mut b, term);
  41. xor_w(&mut a, w_low, w_high);
  42. apply_p(&mut a, &mut b, &c, term);
  43. for _ in 0..3 {
  44. swap_bc(&mut b, &mut c);
  45. xor_w(&mut a, w_low, w_high);
  46. apply_p(&mut a, &mut b, &c, term);
  47. }
  48. unsafe { *(b[8..16].as_ptr() as *const [u8; 32]) }
  49. }
  50.  
  51. #[inline(always)]
  52. fn input_block_add(b: &mut [u32; 16], data: &[u32]) {
  53. for (element, data) in b.iter_mut().zip(data.iter()) {
  54. *element = element.wrapping_add(*data);
  55. }
  56. }
  57.  
  58. #[inline(always)]
  59. fn input_block_sub(c: &mut [u32; 16], data: &[u32]) {
  60. for (element, data) in c.iter_mut().zip(data.iter()) {
  61. *element = element.wrapping_sub(*data);
  62. }
  63. }
  64.  
  65. #[inline(always)]
  66. fn xor_w(a: &mut [u32; 12], w_low: u32, w_high: u32) {
  67. a[0] ^= w_low;
  68. a[1] ^= w_high;
  69. }
  70.  
  71. #[inline(always)]
  72. fn apply_p(a: &mut [u32; 12], b: &mut [u32; 16], c: &[u32; 16], data: &[u32]) {
  73. for element in b.iter_mut() {
  74. *element = element.wrapping_shl(17) | element.wrapping_shr(15);
  75. }
  76. perm(a, b, c, data);
  77. a[0] = a[0]
  78. .wrapping_add(c[11])
  79. .wrapping_add(c[15])
  80. .wrapping_add(c[3]);
  81. a[1] = a[1]
  82. .wrapping_add(c[12])
  83. .wrapping_add(c[0])
  84. .wrapping_add(c[4]);
  85. a[2] = a[2]
  86. .wrapping_add(c[13])
  87. .wrapping_add(c[1])
  88. .wrapping_add(c[5]);
  89. a[3] = a[3]
  90. .wrapping_add(c[14])
  91. .wrapping_add(c[2])
  92. .wrapping_add(c[6]);
  93. a[4] = a[4]
  94. .wrapping_add(c[15])
  95. .wrapping_add(c[3])
  96. .wrapping_add(c[7]);
  97. a[5] = a[5]
  98. .wrapping_add(c[0])
  99. .wrapping_add(c[4])
  100. .wrapping_add(c[8]);
  101. a[6] = a[6]
  102. .wrapping_add(c[1])
  103. .wrapping_add(c[5])
  104. .wrapping_add(c[9]);
  105. a[7] = a[7]
  106. .wrapping_add(c[2])
  107. .wrapping_add(c[6])
  108. .wrapping_add(c[10]);
  109. a[8] = a[8]
  110. .wrapping_add(c[3])
  111. .wrapping_add(c[7])
  112. .wrapping_add(c[11]);
  113. a[9] = a[9]
  114. .wrapping_add(c[4])
  115. .wrapping_add(c[8])
  116. .wrapping_add(c[12]);
  117. a[10] = a[10]
  118. .wrapping_add(c[5])
  119. .wrapping_add(c[9])
  120. .wrapping_add(c[13]);
  121. a[11] = a[11]
  122. .wrapping_add(c[6])
  123. .wrapping_add(c[10])
  124. .wrapping_add(c[14]);
  125. }
  126.  
  127. #[inline(always)]
  128. fn perm_elt(
  129. a: &mut [u32; 12],
  130. b: &mut [u32; 16],
  131. xa0: usize,
  132. xa1: usize,
  133. xb0: usize,
  134. xb1: usize,
  135. xb2: usize,
  136. xb3: usize,
  137. xc: u32,
  138. xm: u32,
  139. ) {
  140. unsafe {
  141. *a.get_unchecked_mut(xa0) = (a.get_unchecked(xa0)
  142. ^ ((a.get_unchecked(xa1).wrapping_shl(15u32)
  143. | a.get_unchecked(xa1).wrapping_shr(17u32))
  144. .wrapping_mul(5u32))
  145. ^ xc)
  146. .wrapping_mul(3u32)
  147. ^ b.get_unchecked(xb1)
  148. ^ (b.get_unchecked(xb2) & !b.get_unchecked(xb3))
  149. ^ xm;
  150. *b.get_unchecked_mut(xb0) = !((b.get_unchecked(xb0).wrapping_shl(1)
  151. | b.get_unchecked(xb0).wrapping_shr(31))
  152. ^ a.get_unchecked(xa0));
  153. }
  154. }
  155.  
  156. #[inline(always)]
  157. fn perm(a: &mut [u32; 12], b: &mut [u32; 16], c: &[u32; 16], data: &[u32]) {
  158. unsafe {
  159. perm_elt(a, b, 0, 11, 0, 13, 9, 6, c[8], *data.get_unchecked(0));
  160. perm_elt(a, b, 1, 0, 1, 14, 10, 7, c[7], *data.get_unchecked(1));
  161. perm_elt(a, b, 2, 1, 2, 15, 11, 8, c[6], *data.get_unchecked(2));
  162. perm_elt(a, b, 3, 2, 3, 0, 12, 9, c[5], *data.get_unchecked(3));
  163. perm_elt(a, b, 4, 3, 4, 1, 13, 10, c[4], *data.get_unchecked(4));
  164. perm_elt(a, b, 5, 4, 5, 2, 14, 11, c[3], *data.get_unchecked(5));
  165. perm_elt(a, b, 6, 5, 6, 3, 15, 12, c[2], *data.get_unchecked(6));
  166. perm_elt(a, b, 7, 6, 7, 4, 0, 13, c[1], *data.get_unchecked(7));
  167. perm_elt(a, b, 8, 7, 8, 5, 1, 14, c[0], *data.get_unchecked(8));
  168. perm_elt(a, b, 9, 8, 9, 6, 2, 15, c[15], *data.get_unchecked(9));
  169. perm_elt(a, b, 10, 9, 10, 7, 3, 0, c[14], *data.get_unchecked(10));
  170. perm_elt(a, b, 11, 10, 11, 8, 4, 1, c[13], *data.get_unchecked(11));
  171. perm_elt(a, b, 0, 11, 12, 9, 5, 2, c[12], *data.get_unchecked(12));
  172. perm_elt(a, b, 1, 0, 13, 10, 6, 3, c[11], *data.get_unchecked(13));
  173. perm_elt(a, b, 2, 1, 14, 11, 7, 4, c[10], *data.get_unchecked(14));
  174. perm_elt(a, b, 3, 2, 15, 12, 8, 5, c[9], *data.get_unchecked(15));
  175. perm_elt(a, b, 4, 3, 0, 13, 9, 6, c[8], *data.get_unchecked(0));
  176. perm_elt(a, b, 5, 4, 1, 14, 10, 7, c[7], *data.get_unchecked(1));
  177. perm_elt(a, b, 6, 5, 2, 15, 11, 8, c[6], *data.get_unchecked(2));
  178. perm_elt(a, b, 7, 6, 3, 0, 12, 9, c[5], *data.get_unchecked(3));
  179. perm_elt(a, b, 8, 7, 4, 1, 13, 10, c[4], *data.get_unchecked(4));
  180. perm_elt(a, b, 9, 8, 5, 2, 14, 11, c[3], *data.get_unchecked(5));
  181. perm_elt(a, b, 10, 9, 6, 3, 15, 12, c[2], *data.get_unchecked(6));
  182. perm_elt(a, b, 11, 10, 7, 4, 0, 13, c[1], *data.get_unchecked(7));
  183. perm_elt(a, b, 0, 11, 8, 5, 1, 14, c[0], *data.get_unchecked(8));
  184. perm_elt(a, b, 1, 0, 9, 6, 2, 15, c[15], *data.get_unchecked(9));
  185. perm_elt(a, b, 2, 1, 10, 7, 3, 0, c[14], *data.get_unchecked(10));
  186. perm_elt(a, b, 3, 2, 11, 8, 4, 1, c[13], *data.get_unchecked(11));
  187. perm_elt(a, b, 4, 3, 12, 9, 5, 2, c[12], *data.get_unchecked(12));
  188. perm_elt(a, b, 5, 4, 13, 10, 6, 3, c[11], *data.get_unchecked(13));
  189. perm_elt(a, b, 6, 5, 14, 11, 7, 4, c[10], *data.get_unchecked(14));
  190. perm_elt(a, b, 7, 6, 15, 12, 8, 5, c[9], *data.get_unchecked(15));
  191. perm_elt(a, b, 8, 7, 0, 13, 9, 6, c[8], *data.get_unchecked(0));
  192. perm_elt(a, b, 9, 8, 1, 14, 10, 7, c[7], *data.get_unchecked(1));
  193. perm_elt(a, b, 10, 9, 2, 15, 11, 8, c[6], *data.get_unchecked(2));
  194. perm_elt(a, b, 11, 10, 3, 0, 12, 9, c[5], *data.get_unchecked(3));
  195. perm_elt(a, b, 0, 11, 4, 1, 13, 10, c[4], *data.get_unchecked(4));
  196. perm_elt(a, b, 1, 0, 5, 2, 14, 11, c[3], *data.get_unchecked(5));
  197. perm_elt(a, b, 2, 1, 6, 3, 15, 12, c[2], *data.get_unchecked(6));
  198. perm_elt(a, b, 3, 2, 7, 4, 0, 13, c[1], *data.get_unchecked(7));
  199. perm_elt(a, b, 4, 3, 8, 5, 1, 14, c[0], *data.get_unchecked(8));
  200. perm_elt(a, b, 5, 4, 9, 6, 2, 15, c[15], *data.get_unchecked(9));
  201. perm_elt(a, b, 6, 5, 10, 7, 3, 0, c[14], *data.get_unchecked(10));
  202. perm_elt(a, b, 7, 6, 11, 8, 4, 1, c[13], *data.get_unchecked(11));
  203. perm_elt(a, b, 8, 7, 12, 9, 5, 2, c[12], *data.get_unchecked(12));
  204. perm_elt(a, b, 9, 8, 13, 10, 6, 3, c[11], *data.get_unchecked(13));
  205. perm_elt(a, b, 10, 9, 14, 11, 7, 4, c[10], *data.get_unchecked(14));
  206. perm_elt(a, b, 11, 10, 15, 12, 8, 5, c[9], *data.get_unchecked(15));
  207. }
  208. }
  209.  
  210. #[inline(always)]
  211. fn swap_bc(b: &mut [u32; 16], c: &mut [u32; 16]) {
  212. std::mem::swap(b, c);
  213. }
  214.  
  215. #[inline(always)]
  216. fn incr_w(w_low: &mut u32, w_high: &mut u32) {
  217. *w_low = w_low.wrapping_add(1);
  218. if *w_low == 0 {
  219. *w_high = w_high.wrapping_add(1);
  220. }
  221. }
  222.  
  223. pub fn main(){
  224. println!("Test");
  225. // Test Burst Block 610206
  226. let mut test_data = [0u8; 64];
  227. let old_gensig = "8aa2747a542306cd8e32e2bb4383e7bb61caa8c38dcc702671247cf609735f4f";
  228. let old_gensig_bytes = decode_hex(&old_gensig).unwrap();
  229. let generator = 4775161288280836628u64;
  230. let generator_bytes: [u8; 8] = unsafe { transmute(generator.to_be()) };
  231. let new_gensig = "d18d75fb35e42d9b2d08d63c102c8b7b56c1744f6ab5c9a00771122a06c9e38e";
  232. let new_gensig_bytes = decode_hex(&new_gensig).unwrap();
  233. test_data[..32].clone_from_slice(&old_gensig_bytes);
  234. test_data[32..40].clone_from_slice(&generator_bytes);
  235. test_data[40] = 0x80;
  236. let data = unsafe { std::mem::transmute::<&[u8; 64], &[u32; 16]>(&test_data)};
  237. let hash_a = shabal256_fast(&[], &data);
  238.  
  239. println!("result : {:?}", hash_a);
  240. println!("reference: {:?}", new_gensig_bytes);
  241.  
  242. // Test BHD Block 610206
  243. let mut test_data = [0u8; 64];
  244. let old_gensig = "3da04d45c43fc1e6a74b28370581e905e64b6eb33499a7e190fc16f780cc3c3c";
  245. let old_gensig_bytes = decode_hex(&old_gensig).unwrap();
  246. let generator = 17718190633864868155u64;
  247. let generator_bytes: [u8; 8] = unsafe { transmute(generator.to_be()) };
  248. let new_gensig = "e874c66401dbf45ccb0437f81386c55fc48d8f0a275230442731d438997dae8a";
  249. let new_gensig_bytes = decode_hex(&new_gensig).unwrap();
  250. test_data[..32].clone_from_slice(&old_gensig_bytes);
  251. test_data[32..40].clone_from_slice(&generator_bytes);
  252. test_data[40] = 0x80;
  253. let data = unsafe { std::mem::transmute::<&[u8; 64], &[u32; 16]>(&test_data)};
  254. let hash_a = shabal256_fast(&[], &data);
  255.  
  256. println!("result : {:?}", hash_a);
  257. println!("reference: {:?}", new_gensig_bytes);
  258.  
  259.  
  260. }
  261.  
  262.  
  263.  
  264. use std::{fmt, num::ParseIntError};
  265.  
  266. pub fn decode_hex(s: &str) -> Result<Vec<u8>, DecodeHexError> {
  267. if s.len() % 2 != 0 {
  268. Err(DecodeHexError::OddLength)
  269. } else {
  270. (0..s.len())
  271. .step_by(2)
  272. .map(|i| u8::from_str_radix(&s[i..i + 2], 16).map_err(|e| e.into()))
  273. .collect()
  274. }
  275. }
  276.  
  277. #[derive(Debug, Clone, PartialEq, Eq)]
  278. pub enum DecodeHexError {
  279. OddLength,
  280. ParseInt(ParseIntError),
  281. }
  282.  
  283. impl From<ParseIntError> for DecodeHexError {
  284. fn from(e: ParseIntError) -> Self {
  285. DecodeHexError::ParseInt(e)
  286. }
  287. }
  288.  
  289. impl fmt::Display for DecodeHexError {
  290. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  291. match self {
  292. DecodeHexError::OddLength => "input string has an odd number of bytes".fmt(f),
  293. DecodeHexError::ParseInt(e) => e.fmt(f),
  294. }
  295. }
  296. }
  297.  
  298. impl std::error::Error for DecodeHexError {}
  299.  
  300.  
  301. #[cfg(test)]
  302. mod test {
  303. use super::*;
  304. const TEST_A_RESULT: [u8; 32] = [
  305. 0xDA, 0x8F, 0x08, 0xC0, 0x2A, 0x67, 0xBA, 0x9A, 0x56, 0xBD, 0xD0, 0x79, 0x8E, 0x48, 0xAE,
  306. 0x07, 0x14, 0x21, 0x5E, 0x09, 0x3B, 0x5B, 0x85, 0x06, 0x49, 0xA3, 0x77, 0x18, 0x99, 0x3F,
  307. 0x54, 0xA2,
  308. ];
  309. const TEST_B_RESULT: [u8; 32] = [
  310. 0xB4, 0x9F, 0x34, 0xBF, 0x51, 0x86, 0x4C, 0x30, 0x53, 0x3C, 0xC4, 0x6C, 0xC2, 0x54, 0x2B,
  311. 0xDE, 0xC2, 0xF9, 0x6F, 0xD0, 0x6F, 0x5C, 0x53, 0x9A, 0xFF, 0x6E, 0xAD, 0x58, 0x83, 0xF7,
  312. 0x32, 0x7A,
  313. ];
  314. const TEST_B_M1: [u32; 16] = [
  315. 0x64636261, 0x68676665, 0x6C6B6A69, 0x706F6E6D, 0x74737271, 0x78777675, 0x302D7A79,
  316. 0x34333231, 0x38373635, 0x42412D39, 0x46454443, 0x4A494847, 0x4E4D4C4B, 0x5251504F,
  317. 0x56555453, 0x5A595857,
  318. ];
  319. const TEST_B_M2: [u32; 16] = [
  320. 0x3231302D, 0x36353433, 0x2D393837, 0x64636261, 0x68676665, 0x6C6B6A69, 0x706F6E6D,
  321. 0x74737271, 0x78777675, 0x00807A79, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  322. 0x00000000, 0x00000000,
  323. ];
  324.  
  325. #[test]
  326. fn shabal256() {
  327. // test message A
  328. let test_data = [0u8; 64];
  329. let mut test_term = [0u32; 16];
  330. test_term[0] = 0x80;
  331. let hash_a = shabal256_fast(&test_data, &test_term);
  332. assert_eq!(hash_a, TEST_A_RESULT);
  333. // test message B
  334. let hash_b = unsafe {
  335. shabal256_fast(
  336. &std::mem::transmute::<[u32; 16], [u8; 64]>(TEST_B_M1),
  337. &TEST_B_M2,
  338. )
  339. };
  340. assert_eq!(hash_b, TEST_B_RESULT);
  341. }
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement