shine.rs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. use crate::lagrange::*;
  2. use curve25519_dalek::constants as dalek_constants;
  3. use curve25519_dalek::ristretto::RistrettoPoint;
  4. use curve25519_dalek::scalar::Scalar;
  5. use curve25519_dalek::traits::Identity;
  6. use rand::RngCore;
  7. use sha2::Digest;
  8. use sha2::Sha256;
  9. // Compute (m choose k) when m^k < 2^64
  10. fn binom(m: u32, k: u32) -> u64 {
  11. let mut numer = 1u64;
  12. let mut denom = 1u64;
  13. for i in 0u64..(k as u64) {
  14. numer *= (m as u64) - i;
  15. denom *= i + 1;
  16. }
  17. numer / denom
  18. }
  19. fn hash1(theta: &[u8; 16], w: &[u8]) -> Scalar {
  20. let mut hash = Sha256::new();
  21. hash.update(&theta);
  22. hash.update(&w);
  23. let mut hashval = [0u8; 32];
  24. hashval[0..32].copy_from_slice(&hash.finalize());
  25. Scalar::from_bytes_mod_order(hashval)
  26. }
  27. // Iterate over subsets of {1, 2, ..., n} of size k
  28. struct SubsetIter {
  29. n: u32,
  30. k: u32,
  31. done: bool,
  32. nextsubset: Vec<u32>,
  33. }
  34. impl SubsetIter {
  35. pub fn new(n: u32, k: u32) -> Self {
  36. assert!(k >= 1);
  37. assert!(n >= k);
  38. let nextsubset: Vec<u32> = (1..=k).collect();
  39. Self {
  40. n,
  41. k,
  42. done: false,
  43. nextsubset,
  44. }
  45. }
  46. }
  47. impl Iterator for SubsetIter {
  48. type Item = Vec<u32>;
  49. fn next(&mut self) -> Option<Self::Item> {
  50. let mut incindex: usize = 0;
  51. let ku = self.k as usize;
  52. let res = if self.done {
  53. None
  54. } else {
  55. Some(self.nextsubset.clone())
  56. };
  57. while incindex < ku && self.nextsubset[ku - 1 - incindex] == self.n - (incindex as u32) {
  58. incindex += 1;
  59. }
  60. if incindex < ku {
  61. self.nextsubset[ku - 1 - incindex] += 1;
  62. for i in 0..incindex {
  63. self.nextsubset[ku - incindex + i] =
  64. self.nextsubset[ku - 1 - incindex] + (i as u32) + 1;
  65. }
  66. } else {
  67. self.done = true;
  68. }
  69. res
  70. }
  71. }
  72. #[test]
  73. pub fn test_subsetiter() {
  74. let si = SubsetIter::new(7, 4);
  75. for v in si {
  76. println!("{:?}", v);
  77. }
  78. }
  79. // The key for player k will consist of a vector of (v, theta) tuples,
  80. // where the v values enumerate all lists of t-1 player numbers (from
  81. // 1 to n) that do _not_ include k
  82. #[derive(Debug)]
  83. pub struct Key {
  84. pub n: u32,
  85. pub t: u32,
  86. pub k: u32,
  87. pub secrets: Vec<(Vec<u32>, [u8; 16])>,
  88. }
  89. impl Key {
  90. pub fn keygen(n: u32, t: u32) -> Vec<Self> {
  91. let mut rng = rand::thread_rng();
  92. let mut res: Vec<Self> = Vec::new();
  93. for k in 1..=n {
  94. res.push(Self {
  95. n,
  96. t,
  97. k,
  98. secrets: Vec::new(),
  99. });
  100. }
  101. let si = SubsetIter::new(n, t - 1);
  102. for v in si {
  103. // For each subset of size t-1, pick a random secret, and
  104. // give it to all players _not_ in that subset
  105. let mut theta: [u8; 16] = [0; 16];
  106. rng.fill_bytes(&mut theta);
  107. let mut vnextind = 0usize;
  108. let mut vnext = v[0];
  109. for i in 1..=n {
  110. if i < vnext {
  111. res[(i - 1) as usize]
  112. .secrets
  113. .push((v.clone(), theta.clone()));
  114. } else {
  115. vnextind += 1;
  116. vnext = if vnextind < ((t - 1) as usize) {
  117. v[vnextind]
  118. } else {
  119. n + 1
  120. };
  121. }
  122. }
  123. }
  124. res
  125. }
  126. }
  127. #[test]
  128. pub fn test_keygen() {
  129. let keys = Key::keygen(7, 4);
  130. println!("key for player 3: {:?}", keys[2]);
  131. println!("key for player 7: {:?}", keys[6]);
  132. }
  133. #[derive(Debug)]
  134. pub struct PreprocKey {
  135. pub n: u32,
  136. pub t: u32,
  137. pub k: u32,
  138. pub secrets: Vec<([u8; 16], Scalar)>,
  139. }
  140. impl PreprocKey {
  141. pub fn preproc(key: &Key) -> Self {
  142. Self {
  143. n: key.n,
  144. t: key.t,
  145. k: key.k,
  146. secrets: key
  147. .secrets
  148. .iter()
  149. .map(|(v, theta)| (theta.clone(), lagrange(&v, 0, key.k)))
  150. .collect(),
  151. }
  152. }
  153. pub fn rand(n: u32, t: u32) -> Self {
  154. let delta = binom(n - 1, t - 1);
  155. let mut secrets: Vec<([u8; 16], Scalar)> = Vec::new();
  156. let mut rng = rand::thread_rng();
  157. for _ in 0u64..delta {
  158. let mut theta = [0u8; 16];
  159. rng.fill_bytes(&mut theta);
  160. let lagrange: Scalar = Scalar::random(&mut rng);
  161. secrets.push((theta, lagrange));
  162. }
  163. Self {
  164. n,
  165. t,
  166. k: 1,
  167. secrets,
  168. }
  169. }
  170. pub fn partialeval(&self, w: &[u8]) -> Scalar {
  171. self.secrets
  172. .iter()
  173. .map(|&(theta, lagrange)| hash1(&theta, &w) * lagrange)
  174. .sum()
  175. }
  176. pub fn delta(&self) -> usize {
  177. self.secrets.len()
  178. }
  179. }
  180. pub fn commit(evaluation: &Scalar) -> RistrettoPoint {
  181. evaluation * &dalek_constants::RISTRETTO_BASEPOINT_TABLE
  182. }
  183. // Combine commitments using precomputed Lagrange polynomials. Return
  184. // None if the commitments are not consistent with the given t. You
  185. // must pass at least 2t-1 commitments, and the same number of
  186. // lag_polys.
  187. pub fn combinecomm_polys(
  188. t: u32,
  189. lag_polys: &[ScalarPoly],
  190. commitments: &[RistrettoPoint],
  191. ) -> Option<RistrettoPoint> {
  192. // Check if the commitments are consistent: when interpolating the
  193. // polys in the exponent, the low t coefficients can be non-0 but
  194. // the ones above that must be 0
  195. let mu = commitments.len();
  196. assert!(t >= 1);
  197. assert!(mu >= 2 * (t as usize) - 1);
  198. assert!(mu == lag_polys.len());
  199. assert!(mu == lag_polys[0].coeffs.len());
  200. if ((t as usize)..mu)
  201. .map(|i| {
  202. (0..mu)
  203. .map(|j| lag_polys[j].coeffs[i] * commitments[j])
  204. .sum()
  205. })
  206. .any(|bi: RistrettoPoint| bi != RistrettoPoint::identity())
  207. {
  208. return None;
  209. }
  210. Some(
  211. (0..mu)
  212. .map(|j| lag_polys[j].coeffs[0] * commitments[j])
  213. .sum(),
  214. )
  215. }
  216. // Combine commitments. Return None if the commitments are not
  217. // consistent with the given t. You must pass at least 2t-1
  218. // commitments, and the same size of coalition.
  219. pub fn combinecomm(
  220. t: u32,
  221. coalition: &[u32],
  222. commitments: &[RistrettoPoint],
  223. ) -> Option<RistrettoPoint> {
  224. let polys = lagrange_polys(coalition);
  225. combinecomm_polys(t, &polys, commitments)
  226. }
  227. #[test]
  228. pub fn test_preproc() {
  229. let keys = Key::keygen(7, 4);
  230. let ppkey3 = PreprocKey::preproc(&keys[2]);
  231. let ppkey7 = PreprocKey::preproc(&keys[6]);
  232. println!("preproc key for player 3: {:?}", ppkey3);
  233. println!("preproc key for player 7: {:?}", ppkey7);
  234. }
  235. #[test]
  236. pub fn test_partialeval() {
  237. let keys = Key::keygen(7, 3);
  238. let ppkeys: Vec<PreprocKey> = keys.iter().map(|x| PreprocKey::preproc(x)).collect();
  239. let mut rng = rand::thread_rng();
  240. let mut w = [0u8; 32];
  241. rng.fill_bytes(&mut w);
  242. let evals: Vec<Scalar> = ppkeys.iter().map(|k| k.partialeval(&w)).collect();
  243. // Try interpolating different subsets and check that the answer is
  244. // the same
  245. let interp1 = interpolate(&vec![1, 2, 3, 4, 5], &evals[0..=4], 0);
  246. let interp2 = interpolate(&vec![3, 4, 5, 6, 7], &evals[2..=6], 0);
  247. println!("interp1 = {:?}", interp1);
  248. println!("interp2 = {:?}", interp2);
  249. assert!(interp1 == interp2);
  250. }
  251. #[test]
  252. pub fn test_combinecomm() {
  253. let keys = Key::keygen(7, 3);
  254. let ppkeys: Vec<PreprocKey> = keys.iter().map(|x| PreprocKey::preproc(x)).collect();
  255. let mut rng = rand::thread_rng();
  256. let mut w = [0u8; 32];
  257. rng.fill_bytes(&mut w);
  258. let commitments: Vec<RistrettoPoint> =
  259. ppkeys.iter().map(|k| commit(&k.partialeval(&w))).collect();
  260. let comm1 = combinecomm(3, &vec![1, 2, 3, 4, 5], &commitments[0..=4]);
  261. let comm2 = combinecomm(3, &vec![3, 4, 5, 6, 7], &commitments[2..=6]);
  262. assert_ne!(comm1, None);
  263. assert_ne!(comm2, None);
  264. // Test a failure case
  265. let comm3 = combinecomm(3, &vec![1, 2, 3, 4, 6], &commitments[0..=4]);
  266. assert_eq!(comm3, None);
  267. }