Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: RustCrypto/universal-hashes
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: fe4e76218faa306e474948f2a1c82db466029ed2
Choose a base ref
..
head repository: RustCrypto/universal-hashes
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a5b36f719b76208b883e044474c120993910c997
Choose a head ref
Showing with 19 additions and 8 deletions.
  1. +19 −8 polyval/src/field/backend/soft.rs
27 changes: 19 additions & 8 deletions polyval/src/field/backend/soft.rs
Original file line number Diff line number Diff line change
@@ -84,8 +84,24 @@ impl Add for U64x2 {
impl Mul for U64x2 {
type Output = Self;

/// Computes POLYVAL multiplication over GF(2^128).
// TODO(tarcieri): actually adapt the arithmetic below from GHASH
/// Computes POLYVAL multiplication over GF(2^128) in constant time.
///
/// Method described at:
/// <https://www.bearssl.org/constanttime.html#ghash-for-gcm>
///
/// POLYVAL multiplication is effectively the little endian equivalent of
/// GHASH multiplication, aside from one small detail described here:
///
/// <https://crypto.stackexchange.com/questions/66448/how-does-bearssls-gcm-modular-reduction-work/66462#66462>
///
/// > If you look at the equation above, the product of two bit-reversed
/// > 128-bit polynomials yields the bit-reversed result over 255 bits,
/// > not 256. The BearSSL code ends up with a 256-bit result in zw[],
/// > and that value is shifted by one bit, because of that reversed
/// > convention issue. Thus, the code must include a shifting step to put
/// > it back where it should
///
/// This shift is unnecessary for POLYVAL.
fn mul(self, rhs: Self) -> Self {
let h0 = self.0;
let h1 = self.1;
@@ -114,16 +130,11 @@ impl Mul for U64x2 {
z1h = rev64(z1h) >> 1;
z2h = rev64(z2h) >> 1;

let mut v0 = z0;
let v0 = z0;
let mut v1 = z0h ^ z2;
let mut v2 = z1 ^ z2h;
let mut v3 = z1h;

v3 = v3 << 1 | v2 >> 63;
v2 = v2 << 1 | v1 >> 63;
v1 = v1 << 1 | v0 >> 63;
v0 <<= 1;

v2 ^= v0 ^ v0 >> 1 ^ v0 >> 2 ^ v0 >> 7;
v1 ^= v0 << 63 ^ v0 << 62 ^ v0 << 57;
v3 ^= v1 ^ v1 >> 1 ^ v1 >> 2 ^ v1 >> 7;