| ... | ... | @@ -1031,14 +1031,18 @@ pub fn Modulus(comptime max_bits: comptime_int) type { |
| 1031 | 1031 | } |
| 1032 | 1032 | } |
| 1033 | 1033 | |
| 1034 | const max_encoded_bytes = @divCeil(FeUint.capacity_bits, 8); |
| 1035 | |
| 1034 | 1036 | /// Returns x^e (mod m) in constant time. |
| 1035 | 1037 | pub fn pow(self: Self, x: Fe, e: Fe) (NullExponentError || RepresentationError)!Fe { |
| 1036 | 1038 | if (e.montgomery) { |
| 1037 | 1039 | return error.UnexpectedRepresentation; |
| 1038 | 1040 | } |
| 1039 | | var buf: [Fe.encoded_bytes]u8 = undefined; |
| 1040 | | e.toBytes(&buf, native_endian) catch unreachable; |
| 1041 | | return self.powWithEncodedExponent(x, &buf, native_endian); |
| 1041 | |
| 1042 | var buf: [max_encoded_bytes]u8 = undefined; |
| 1043 | const len = self.encodedLen(); |
| 1044 | e.toBytes(buf[0..len], native_endian) catch unreachable; |
| 1045 | return self.powWithEncodedExponent(x, buf[0..len], native_endian); |
| 1042 | 1046 | } |
| 1043 | 1047 | |
| 1044 | 1048 | /// Returns x^e (mod m), assuming that the exponent is public. |
| ... | ... | @@ -1047,12 +1051,9 @@ pub fn Modulus(comptime max_bits: comptime_int) type { |
| 1047 | 1051 | if (e.montgomery) { |
| 1048 | 1052 | return error.UnexpectedRepresentation; |
| 1049 | 1053 | } |
| 1050 | | var e_normalized = Fe{ .v = e.v.normalize() }; |
| 1051 | | var buf_: [Fe.encoded_bytes]u8 = undefined; |
| 1052 | | var buf = buf_[0..@divCeil(e_normalized.v.limbs_len * t_bits, 8)]; |
| 1053 | | e_normalized.toBytes(buf, .little) catch unreachable; |
| 1054 | | const leading = @clz(e_normalized.v.limbsConst()[e_normalized.v.limbs_len - carry_bits]); |
| 1055 | | buf = buf[0 .. buf.len - leading / 8]; |
| 1054 | var buf_: [max_encoded_bytes]u8 = undefined; |
| 1055 | const buf = buf_[0..@divCeil(e.v.bitLenPublic(), 8)]; |
| 1056 | e.toBytes(buf, .little) catch unreachable; |
| 1056 | 1057 | return self.powWithEncodedPublicExponent(x, buf, .little); |
| 1057 | 1058 | } |
| 1058 | 1059 | |