rangeutils.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. //! A module containing some utility functions useful for the runtime
  2. //! processing of range statements.
  3. use group::ff::PrimeField;
  4. use sigma_proofs::errors::InvalidInstance;
  5. use subtle::Choice;
  6. /// Convert a [`Scalar`] to an [`u128`], assuming it fits in an [`i128`]
  7. /// and is nonnegative. Also output the number of bits of the
  8. /// [`Scalar`]. This version assumes that `s` is public, and so does
  9. /// not need to run in constant time.
  10. ///
  11. /// [`Scalar`]: https://docs.rs/group/0.13.0/group/trait.Group.html#associatedtype.Scalar
  12. pub fn bit_decomp_vartime<S: PrimeField>(mut s: S) -> Option<(u128, u32)> {
  13. let mut val = 0u128;
  14. let mut bitnum = 0u32;
  15. let mut bitval = 1u128; // Invariant: bitval = 2^bitnum
  16. while bitnum < 127 && !s.is_zero_vartime() {
  17. if s.is_odd().into() {
  18. val += bitval;
  19. s -= S::ONE;
  20. }
  21. bitnum += 1;
  22. bitval <<= 1;
  23. s *= S::TWO_INV;
  24. }
  25. if s.is_zero_vartime() {
  26. Some((val, bitnum))
  27. } else {
  28. None
  29. }
  30. }
  31. /// Convert the low `nbits` bits of the given [`Scalar`] to a vector of
  32. /// [`Choice`]. The first element of the vector is the low bit. This
  33. /// version runs in constant time.
  34. ///
  35. /// [`Scalar`]: https://docs.rs/group/0.13.0/group/trait.Group.html#associatedtype.Scalar
  36. pub fn bit_decomp<S: PrimeField>(mut s: S, nbits: u32) -> Vec<Choice> {
  37. let mut bits = Vec::with_capacity(nbits as usize);
  38. let mut bitnum = 0u32;
  39. while bitnum < nbits && bitnum < 127 {
  40. let lowbit = s.is_odd();
  41. s -= S::conditional_select(&S::ZERO, &S::ONE, lowbit);
  42. s *= S::TWO_INV;
  43. bits.push(lowbit);
  44. bitnum += 1;
  45. }
  46. bits
  47. }
  48. /// Given a [`Scalar`] `upper` (strictly greater than 1), make a vector
  49. /// of [`Scalar`]s with the property that a [`Scalar`] `x` can be
  50. /// written as a sum of zero or more (distinct) elements of this vector
  51. /// if and only if `0 <= x < upper`.
  52. ///
  53. /// The strategy is to write x as a sequence of `nbits` bits, with one
  54. /// twist: the low bits represent 2^0, 2^1, 2^2, etc., as usual. But
  55. /// the highest bit represents `upper-2^{nbits-1}` instead of the usual
  56. /// `2^{nbits-1}`. `nbits` will be the largest value for which
  57. /// `2^{nbits-1}` is strictly less than `upper`. For example, if
  58. /// `upper` is 100, the bits represent 1, 2, 4, 8, 16, 32, 36. A number
  59. /// x can be represented as a sum of 0 or more elements of this sequence
  60. /// if and only if `0 <= x < upper`.
  61. ///
  62. /// It is assumed that `upper` is public, and so this function is not
  63. /// constant time.
  64. ///
  65. /// [`Scalar`]: https://docs.rs/group/0.13.0/group/trait.Group.html#associatedtype.Scalar
  66. pub fn bitrep_scalars_vartime<S: PrimeField>(upper: S) -> Result<Vec<S>, InvalidInstance> {
  67. // Get the `u128` value of `upper`, and its number of bits `nbits`
  68. let (upper_val, mut nbits) = bit_decomp_vartime(upper)
  69. .ok_or_else(|| InvalidInstance::new("range upper bound exceeds i128::MAX"))?;
  70. // Ensure `nbits` is at least 2.
  71. if nbits < 2 {
  72. return Err(InvalidInstance::new("range upper bound must be at least 2"));
  73. }
  74. // If upper is exactly a power of 2, use one fewer bit
  75. if upper_val == 1u128 << (nbits - 1) {
  76. nbits -= 1;
  77. }
  78. // Make the vector of Scalars containing the represented value of
  79. // the bits
  80. Ok((0..nbits)
  81. .map(|i| {
  82. if i < nbits - 1 {
  83. S::from_u128(1u128 << i)
  84. } else {
  85. // Compute the represented value of the highest bit
  86. S::from_u128(upper_val - (1u128 << (nbits - 1)))
  87. }
  88. })
  89. .collect())
  90. }
  91. /// Given a vector of [`Scalar`]s as output by
  92. /// [`bitrep_scalars_vartime`] and a private [`Scalar`] `x`, output a
  93. /// vector of [`Choice`] (of the same length as the given
  94. /// `bitrep_scalars` vector) such that `x` is the sum of the chosen
  95. /// elements of `bitrep_scalars`. This function should be constant time
  96. /// in the value of `x`. If `x` is not less than the `upper` used by
  97. /// [`bitrep_scalars_vartime`] to generate `bitrep_scalars`, then `x`
  98. /// will not (and indeed cannot) equal the sum of the chosen elements of
  99. /// `bitrep_scalars`.
  100. ///
  101. /// [`Scalar`]: https://docs.rs/group/0.13.0/group/trait.Group.html#associatedtype.Scalar
  102. pub fn compute_bitrep<S: PrimeField>(mut x: S, bitrep_scalars: &[S]) -> Vec<Choice> {
  103. // We know the length of bitrep_scalars is at most 127.
  104. let nbits: u32 = bitrep_scalars.len().try_into().unwrap();
  105. // Decompose `x` as a normal `nbit`-bit vector. This only looks at
  106. // the low `nbits` bits of `x`, so the resulting bit vector forces
  107. // `x < 2^{nbits}`.
  108. let x_raw_bits = bit_decomp(x, nbits);
  109. let high_bit = x_raw_bits[(nbits as usize) - 1];
  110. // Conditionally subtract the last represented value in the
  111. // vector, depending on whether the high bit of x is set. That is,
  112. // if `x < 2^{nbits-1}`, then we don't subtract from x. If `x >=
  113. // 2^{nbits-1}`, then we will subtract `upper - 2^{nbits-1}` from
  114. // `x`. In either case, the remaining value is non-negative, and
  115. // strictly less than 2^{nbits-1}.
  116. x -= S::conditional_select(&S::ZERO, &bitrep_scalars[(nbits as usize) - 1], high_bit);
  117. // Now get the `nbits-1` bits of the result in the usual way
  118. let mut x_bits = bit_decomp(x, nbits - 1);
  119. // and tack on the high bit
  120. x_bits.push(high_bit);
  121. x_bits
  122. }
  123. #[cfg(test)]
  124. mod tests {
  125. use super::*;
  126. use curve25519_dalek::scalar::Scalar;
  127. use std::ops::Neg;
  128. use subtle::ConditionallySelectable;
  129. fn bit_decomp_tester(s: Scalar, nbits: u32, expect_bitstr: &str) {
  130. // Convert the expected string of '0' and '1' into a vector of
  131. // Choice
  132. assert_eq!(
  133. bit_decomp(s, nbits)
  134. .into_iter()
  135. .map(|c| char::from(u8::conditional_select(&b'0', &b'1', c)))
  136. .collect::<String>(),
  137. expect_bitstr
  138. );
  139. }
  140. #[test]
  141. fn bit_decomp_test() {
  142. assert_eq!(bit_decomp_vartime(Scalar::from(0u32)), Some((0, 0)));
  143. assert_eq!(bit_decomp_vartime(Scalar::from(1u32)), Some((1, 1)));
  144. assert_eq!(bit_decomp_vartime(Scalar::from(2u32)), Some((2, 2)));
  145. assert_eq!(bit_decomp_vartime(Scalar::from(3u32)), Some((3, 2)));
  146. assert_eq!(bit_decomp_vartime(Scalar::from(4u32)), Some((4, 3)));
  147. assert_eq!(bit_decomp_vartime(Scalar::from(5u32)), Some((5, 3)));
  148. assert_eq!(bit_decomp_vartime(Scalar::from(6u32)), Some((6, 3)));
  149. assert_eq!(bit_decomp_vartime(Scalar::from(7u32)), Some((7, 3)));
  150. assert_eq!(bit_decomp_vartime(Scalar::from(8u32)), Some((8, 4)));
  151. assert_eq!(bit_decomp_vartime(Scalar::from(1u32).neg()), None);
  152. assert_eq!(
  153. bit_decomp_vartime(Scalar::from((1u128 << 127) - 2)),
  154. Some(((i128::MAX - 1) as u128, 127))
  155. );
  156. assert_eq!(
  157. bit_decomp_vartime(Scalar::from((1u128 << 127) - 1)),
  158. Some((i128::MAX as u128, 127))
  159. );
  160. assert_eq!(bit_decomp_vartime(Scalar::from(1u128 << 127)), None);
  161. bit_decomp_tester(Scalar::from(0u32), 0, "");
  162. bit_decomp_tester(Scalar::from(0u32), 5, "00000");
  163. bit_decomp_tester(Scalar::from(1u32), 0, "");
  164. bit_decomp_tester(Scalar::from(1u32), 1, "1");
  165. bit_decomp_tester(Scalar::from(2u32), 1, "0");
  166. bit_decomp_tester(Scalar::from(2u32), 2, "01");
  167. bit_decomp_tester(Scalar::from(3u32), 1, "1");
  168. bit_decomp_tester(Scalar::from(3u32), 2, "11");
  169. bit_decomp_tester(Scalar::from(5u32), 8, "10100000");
  170. // The order of this Scalar group is
  171. // 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
  172. bit_decomp_tester(
  173. Scalar::from(1u32).neg(),
  174. 32,
  175. "00110111110010111010111100111010",
  176. );
  177. bit_decomp_tester(Scalar::from((1u128 << 127) - 2), 127,
  178. "0111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
  179. );
  180. bit_decomp_tester(Scalar::from((1u128 << 127) - 1), 127,
  181. "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
  182. );
  183. bit_decomp_tester(Scalar::from(1u128 << 127), 127,
  184. "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  185. );
  186. bit_decomp_tester(Scalar::from(1u128 << 127), 128,
  187. "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  188. );
  189. }
  190. // Obliviously test whether x is in 0..upper (that is, 0 <= x <
  191. // upper) using bit decomposition. `upper` is considered public,
  192. // but `x` is private. `upper` must be at least 2.
  193. fn bitrep_tester(upper: Scalar, x: Scalar, expected: bool) -> Result<(), InvalidInstance> {
  194. let rep_scalars = bitrep_scalars_vartime(upper)?;
  195. let bitrep = compute_bitrep(x, &rep_scalars);
  196. let nbits = bitrep.len();
  197. assert!(nbits == rep_scalars.len());
  198. let mut x_out = Scalar::ZERO;
  199. for i in 0..nbits {
  200. x_out += Scalar::conditional_select(&Scalar::ZERO, &rep_scalars[i], bitrep[i]);
  201. }
  202. if (x == x_out) != expected {
  203. return Err(InvalidInstance::new(
  204. "bit representation disagrees with the range",
  205. ));
  206. }
  207. Ok(())
  208. }
  209. #[test]
  210. fn bitrep_test() {
  211. bitrep_tester(Scalar::from(0u32), Scalar::from(0u32), false).unwrap_err();
  212. bitrep_tester(Scalar::from(1u32), Scalar::from(0u32), true).unwrap_err();
  213. bitrep_tester(Scalar::from(2u32), Scalar::from(1u32), true).unwrap();
  214. bitrep_tester(Scalar::from(3u32), Scalar::from(1u32), true).unwrap();
  215. bitrep_tester(Scalar::from(100u32), Scalar::from(99u32), true).unwrap();
  216. bitrep_tester(Scalar::from(127u32), Scalar::from(126u32), true).unwrap();
  217. bitrep_tester(Scalar::from(128u32), Scalar::from(127u32), true).unwrap();
  218. bitrep_tester(Scalar::from(128u32), Scalar::from(128u32), false).unwrap();
  219. bitrep_tester(Scalar::from(129u32), Scalar::from(128u32), true).unwrap();
  220. bitrep_tester(Scalar::from(129u32), Scalar::from(0u32), true).unwrap();
  221. bitrep_tester(Scalar::from(129u32), Scalar::from(129u32), false).unwrap();
  222. }
  223. }