Bouncy Castle Cryptography Library 1.85

org.bouncycastle.pqc.crypto.hawk
Class HawkSigner

java.lang.Object
  extended byorg.bouncycastle.pqc.crypto.hawk.HawkSigner
All Implemented Interfaces:
MessageSigner

public class HawkSigner
extends java.lang.Object
implements MessageSigner

Lightweight Hawk signer / verifier. Implements MessageSigner: initialise with a HawkPrivateKeyParameters (optionally wrapped in ParametersWithRandom) for signing, or with a HawkPublicKeyParameters for verification, then call generateSignature(byte[]) / verifySignature(byte[], byte[]).

generateSignature(byte[]) returns the signature bytes only; the NIST "signed message" form () is reconstructed by callers when needed.


Field Summary
static int SG_MAX_HI_HAWK_1024
           
static int SG_MAX_HI_HAWK_256
           
static int SG_MAX_HI_HAWK_512
           
static int SG_MAX_LO_HAWK_1024
           
static int SG_MAX_LO_HAWK_256
           
static int SG_MAX_LO_HAWK_512
           
static short[] SIG_GAUSS_HI_HAWK_1024
           
static short[] SIG_GAUSS_HI_HAWK_256
           
static short[] SIG_GAUSS_HI_HAWK_512
           
static long[] SIG_GAUSS_LO_HAWK_1024
           
static long[] SIG_GAUSS_LO_HAWK_256
           
static long[] SIG_GAUSS_LO_HAWK_512
           
static int SIZE_128
           
static int SIZE_256
           
static int SIZE_512
           
static int SIZE_64
           
 
Constructor Summary
HawkSigner()
           
 
Method Summary
static void basisM2Mul(int logn, byte[] t0, int t0Offset, byte[] t1, int t1Offset, byte[] h0, int h0Offset, byte[] h1, int h1Offset, byte[] f2, int f2Offset, byte[] g2, int g2Offset, byte[] F2, int F2Offset, byte[] G2, int G2Offset, byte[] tmp, int tmpOffset)
           
static long bpMul32(int x, int y)
          Optimized binary polynomial multiplication of two 32-bit values in GF(2) Returns 64-bit product (carry-less multiplication) This implements the same "classic technique" as the C code using the 4-way decomposition with masks
static void bpMuladd(int size, byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset, byte[] tmp, int tmpOffset)
          Binary polynomial multiplication using Karatsuba algorithm d += a * b (polynomial multiplication in GF(2))
static void bpMuladd128(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset, byte[] tmp, int tmpOffset)
           
static void bpMuladd256(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset, byte[] tmp, int tmpOffset)
          Binary polynomial multiplication and accumulation for 256-bit polynomials Uses Karatsuba algorithm with 128-bit halves
static void bpMuladd512(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset, byte[] tmp, int tmpOffset)
          Binary polynomial multiplication and accumulation for 512-bit polynomials Uses Karatsuba algorithm with 256-bit halves
static void bpMuladd64(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset, byte[] tmp, int tmpOffset)
          Binary polynomial multiplication and accumulation for 64-bit polynomials d += a * b (polynomial multiplication in GF(2)) This is a direct translation of the C function that uses 32-bit halves for efficient polynomial multiplication in GF(2)
static void bpXor128(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset)
           
static void bpXor64(byte[] d, int dOffset, byte[] a, int aOffset, byte[] b, int bOffset)
           
 int cryptoSign(byte[] sm, long[] smlen, byte[] m, long mlen, byte[] sk, int logn)
          Main signing function compatible with the crypto_sign API
static int dec16le(byte[] src, int srcOffset)
           
static int dec32le(byte[] src, int srcOffset)
          Decode 32-bit little-endian value from byte array This is a direct translation of the C dec32le function
static long dec64le(byte[] src, int srcOffset)
           
static void enc32le(byte[] dst, int dstOffset, int x)
           
static void enc64le(byte[] dst, int dstOffset, long x)
          Encode 64-bit value as little-endian bytes This is a direct translation of the C enc64le function
static boolean encodeSig(int logn, byte[] sig, int sigOffset, int sigLen, byte[] salt, int saltOffset, int saltLen, short[] s1, int s1Offset)
          Encode the signature, with output length exactly sigLen bytes.
 byte[] generateSignature(byte[] message)
          sign the passed in message (usually the output of a hash function).
static org.bouncycastle.pqc.crypto.hawk.HawkSigner.GaussianTable getGaussianTable(int logn)
           
static int getTmpSize(int polynomialSize)
           
static int hawkPrivKeySize(int logn)
           
 int hawkSignFinish(int logn, byte[] sig, SHAKEDigest scData, byte[] priv, byte[] tmp, int tmpLen)
           
static SHAKEDigest hawkSignStart()
           
static void hawkSignStart(SHAKEDigest sc)
          Start the signing process - initialize SHAKE context
static int hawkSigSize(int logn)
           
static int hawkTmpSizeSign(int logn)
           
 void init(boolean forSigning, CipherParameters param)
          initialise the signer for signature generation or signature verification.
 int mq18433Add(int x, int y)
          Modular addition: (x + y) mod Q, result in [1..Q] where Q represents 0 mod Q.
 int mq18433Half(int x)
          Compute half: x/2 mod Q.
 int mq18433HalfMonty(int x)
          Alternative half implementation using modular inverse of 2
 void mq18433INTT(int logn, short[] a, int aOffset)
          Inverse NTT matching C mq18433_iNTT exactly. 1/n normalization is embedded in the iGM twiddle factors.
 void mq18433INTTWithScaling(int logn, short[] a, int aOffset)
          Alias for mq18433INTT kept for compatibility.
 int mq18433MontyMul(int x, int y)
          Montgomery multiplication: returns (x * y) mod Q in Montgomery form
 int mq18433MontyRed(int x)
          Montgomery reduction.
 void mq18433NTT(int logn, short[] a, int aOffset)
          Number Theoretic Transform (NTT) for modulus 18433
 void mq18433NTTSafe(int logn, short[] a, int aOffset)
          Alternative NTT implementation with explicit bounds checking
 void mq18433PolySetSmall(int logn, short[] d, int dOffset, byte[] a, int aOffset)
          Convert a small polynomial (signed 8-bit coefficients) to mod q representation.
 void mq18433PolySetSmallBatch(int logn, short[][] dArray, int[] dOffsets, byte[][] aArray, int[] aOffsets)
          Batch conversion for multiple polynomials
 void mq18433PolySetSmallInplaceHigh(int logn, short[] d, int dOffset)
          Convert a small polynomial (signed 8-bit coefficients) to a mod q representation that _ends_ at the same address (i.e. the n last bytes of d are read, and 2*n bytes are written into d).
 void mq18433PolySetSmallInplaceLow(int logn, short[] d, int dOffset)
          Convert a small polynomial in-place from packed bytes to mod q representation.
 void mq18433PolySetSmallInplaceLowBatch(int logn, short[][] dArray, int[] dOffsets)
          In-place conversion for multiple polynomials
static void mq18433PolySnorm(int logn, short[] d, int dOffset)
          Apply signed normalization to polynomial coefficients
 short mq18433SetSmall(byte x)
          Convert a signed byte to a mod q value in the range [0, q-1] This is the equivalent of Zq(set_small)
 short mq18433SetSmallSafe(byte x)
          Alternative implementation with bounds checking
static int mq18433Snorm(int x)
          Signed normalization: convert to range [-floor((Q-1)/2), floor((Q-1)/2)].
static int mq18433SnormSafe(int x)
          Alternative signed normalization with proper bounds
 int mq18433Sub(int x, int y)
          Modular subtraction: (x - y) mod Q, result in [1..Q] where Q represents 0 mod Q.
 int mq18433ToMonty(int x)
          Convert a number to Montgomery form
static int polySymBreak(int logn, short[] s, int sOffset)
          Returned value: 1 first non-zero coefficient of s is positive -1 first non-zero coefficient of s is negative 0 s is entirely zero
static int polySymBreakExplicit(int logn, short[] s, int sOffset)
          Alternative implementation with explicit sign detection
 int sigGauss(int logn, SHAKEDigest scExtra, byte[] x, int xOffset, byte[] t, int tOffset)
          Generate x with the right Gaussian, for the specified parity bits.
 int sigGaussAlt(int logn, byte[] x, int xOffset, byte[] t, int tOffset)
          Alternate function for sampling x; the same mechanism is used, but the provided RNG is used directly instead of instantiating four SHAKE instances in parallel.
 byte[] sign(byte[] message, byte[] privateKey, int logn)
          Alternative signature with simpler Java-style API
 int signFinishInner(int logn, int useShake, byte[] sig, SHAKEDigest scData, byte[] priv, int privLen, byte[] tmp, int tmpLen)
           
 boolean verifySignature(byte[] message, byte[] signature)
          verify the message message against the signature value.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SIG_GAUSS_HI_HAWK_256

public static final short[] SIG_GAUSS_HI_HAWK_256

SG_MAX_HI_HAWK_256

public static final int SG_MAX_HI_HAWK_256

SIG_GAUSS_LO_HAWK_256

public static final long[] SIG_GAUSS_LO_HAWK_256

SG_MAX_LO_HAWK_256

public static final int SG_MAX_LO_HAWK_256

SIG_GAUSS_HI_HAWK_512

public static final short[] SIG_GAUSS_HI_HAWK_512

SG_MAX_HI_HAWK_512

public static final int SG_MAX_HI_HAWK_512

SIG_GAUSS_LO_HAWK_512

public static final long[] SIG_GAUSS_LO_HAWK_512

SG_MAX_LO_HAWK_512

public static final int SG_MAX_LO_HAWK_512

SIG_GAUSS_HI_HAWK_1024

public static final short[] SIG_GAUSS_HI_HAWK_1024

SG_MAX_HI_HAWK_1024

public static final int SG_MAX_HI_HAWK_1024

SIG_GAUSS_LO_HAWK_1024

public static final long[] SIG_GAUSS_LO_HAWK_1024

SG_MAX_LO_HAWK_1024

public static final int SG_MAX_LO_HAWK_1024

SIZE_64

public static final int SIZE_64
See Also:
Constant Field Values

SIZE_128

public static final int SIZE_128
See Also:
Constant Field Values

SIZE_256

public static final int SIZE_256
See Also:
Constant Field Values

SIZE_512

public static final int SIZE_512
See Also:
Constant Field Values
Constructor Detail

HawkSigner

public HawkSigner()
Method Detail

init

public void init(boolean forSigning,
                 CipherParameters param)
Description copied from interface: MessageSigner
initialise the signer for signature generation or signature verification.

Specified by:
init in interface MessageSigner
Parameters:
forSigning - true if we are generating a signature, false otherwise.
param - key parameters for signature generation.

generateSignature

public byte[] generateSignature(byte[] message)
Description copied from interface: MessageSigner
sign the passed in message (usually the output of a hash function).

Specified by:
generateSignature in interface MessageSigner
Parameters:
message - the message to be signed.
Returns:
the signature of the message

verifySignature

public boolean verifySignature(byte[] message,
                               byte[] signature)
Description copied from interface: MessageSigner
verify the message message against the signature value.

Specified by:
verifySignature in interface MessageSigner
Parameters:
message - the message that was supposed to have been signed.
signature - the signature of the message

hawkSignStart

public static SHAKEDigest hawkSignStart()

hawkSignFinish

public int hawkSignFinish(int logn,
                          byte[] sig,
                          SHAKEDigest scData,
                          byte[] priv,
                          byte[] tmp,
                          int tmpLen)

basisM2Mul

public static void basisM2Mul(int logn,
                              byte[] t0,
                              int t0Offset,
                              byte[] t1,
                              int t1Offset,
                              byte[] h0,
                              int h0Offset,
                              byte[] h1,
                              int h1Offset,
                              byte[] f2,
                              int f2Offset,
                              byte[] g2,
                              int g2Offset,
                              byte[] F2,
                              int F2Offset,
                              byte[] G2,
                              int G2Offset,
                              byte[] tmp,
                              int tmpOffset)

bpMuladd

public static void bpMuladd(int size,
                            byte[] d,
                            int dOffset,
                            byte[] a,
                            int aOffset,
                            byte[] b,
                            int bOffset,
                            byte[] tmp,
                            int tmpOffset)
Binary polynomial multiplication using Karatsuba algorithm d += a * b (polynomial multiplication in GF(2))


bpMuladd128

public static void bpMuladd128(byte[] d,
                               int dOffset,
                               byte[] a,
                               int aOffset,
                               byte[] b,
                               int bOffset,
                               byte[] tmp,
                               int tmpOffset)

bpXor64

public static void bpXor64(byte[] d,
                           int dOffset,
                           byte[] a,
                           int aOffset,
                           byte[] b,
                           int bOffset)

bpXor128

public static void bpXor128(byte[] d,
                            int dOffset,
                            byte[] a,
                            int aOffset,
                            byte[] b,
                            int bOffset)

getTmpSize

public static int getTmpSize(int polynomialSize)

bpMuladd64

public static void bpMuladd64(byte[] d,
                              int dOffset,
                              byte[] a,
                              int aOffset,
                              byte[] b,
                              int bOffset,
                              byte[] tmp,
                              int tmpOffset)
Binary polynomial multiplication and accumulation for 64-bit polynomials d += a * b (polynomial multiplication in GF(2))

This is a direct translation of the C function that uses 32-bit halves for efficient polynomial multiplication in GF(2)


dec32le

public static int dec32le(byte[] src,
                          int srcOffset)
Decode 32-bit little-endian value from byte array This is a direct translation of the C dec32le function


bpMul32

public static long bpMul32(int x,
                           int y)
Optimized binary polynomial multiplication of two 32-bit values in GF(2) Returns 64-bit product (carry-less multiplication)

This implements the same "classic technique" as the C code using the 4-way decomposition with masks


enc64le

public static void enc64le(byte[] dst,
                           int dstOffset,
                           long x)
Encode 64-bit value as little-endian bytes This is a direct translation of the C enc64le function


bpMuladd256

public static void bpMuladd256(byte[] d,
                               int dOffset,
                               byte[] a,
                               int aOffset,
                               byte[] b,
                               int bOffset,
                               byte[] tmp,
                               int tmpOffset)
Binary polynomial multiplication and accumulation for 256-bit polynomials Uses Karatsuba algorithm with 128-bit halves


bpMuladd512

public static void bpMuladd512(byte[] d,
                               int dOffset,
                               byte[] a,
                               int aOffset,
                               byte[] b,
                               int bOffset,
                               byte[] tmp,
                               int tmpOffset)
Binary polynomial multiplication and accumulation for 512-bit polynomials Uses Karatsuba algorithm with 256-bit halves


enc32le

public static void enc32le(byte[] dst,
                           int dstOffset,
                           int x)

dec64le

public static long dec64le(byte[] src,
                           int srcOffset)

dec16le

public static int dec16le(byte[] src,
                          int srcOffset)

sigGauss

public int sigGauss(int logn,
                    SHAKEDigest scExtra,
                    byte[] x,
                    int xOffset,
                    byte[] t,
                    int tOffset)
Generate x with the right Gaussian, for the specified parity bits. x is formally generated with center t/2 and standard deviation sigma_sign (with sigma_sign = 1.010, 1.278 or 1.299, depending on degree); this function generates 2*x.

Returned value is the squared norm of x.


getGaussianTable

public static org.bouncycastle.pqc.crypto.hawk.HawkSigner.GaussianTable getGaussianTable(int logn)

sigGaussAlt

public int sigGaussAlt(int logn,
                       byte[] x,
                       int xOffset,
                       byte[] t,
                       int tOffset)
Alternate function for sampling x; the same mechanism is used, but the provided RNG is used directly instead of instantiating four SHAKE instances in parallel.

Returned value is the squared norm of x.


mq18433PolySetSmall

public void mq18433PolySetSmall(int logn,
                                short[] d,
                                int dOffset,
                                byte[] a,
                                int aOffset)
Convert a small polynomial (signed 8-bit coefficients) to mod q representation. This is the equivalent of Zq(poly_set_small)


mq18433PolySetSmallInplaceLow

public void mq18433PolySetSmallInplaceLow(int logn,
                                          short[] d,
                                          int dOffset)
Convert a small polynomial in-place from packed bytes to mod q representation. This is the equivalent of Zq(poly_set_small_inplace_low)

The input is stored as packed bytes in the first n/2 elements of d, and the output is written as mod q values in all n elements of d.


mq18433SetSmall

public short mq18433SetSmall(byte x)
Convert a signed byte to a mod q value in the range [0, q-1] This is the equivalent of Zq(set_small)


mq18433SetSmallSafe

public short mq18433SetSmallSafe(byte x)
Alternative implementation with bounds checking


mq18433PolySetSmallBatch

public void mq18433PolySetSmallBatch(int logn,
                                     short[][] dArray,
                                     int[] dOffsets,
                                     byte[][] aArray,
                                     int[] aOffsets)
Batch conversion for multiple polynomials


mq18433PolySetSmallInplaceLowBatch

public void mq18433PolySetSmallInplaceLowBatch(int logn,
                                               short[][] dArray,
                                               int[] dOffsets)
In-place conversion for multiple polynomials


mq18433PolySetSmallInplaceHigh

public void mq18433PolySetSmallInplaceHigh(int logn,
                                           short[] d,
                                           int dOffset)
Convert a small polynomial (signed 8-bit coefficients) to a mod q representation that _ends_ at the same address (i.e. the n last bytes of d are read, and 2*n bytes are written into d).


mq18433NTT

public void mq18433NTT(int logn,
                       short[] a,
                       int aOffset)
Number Theoretic Transform (NTT) for modulus 18433


mq18433NTTSafe

public void mq18433NTTSafe(int logn,
                           short[] a,
                           int aOffset)
Alternative NTT implementation with explicit bounds checking


mq18433MontyMul

public int mq18433MontyMul(int x,
                           int y)
Montgomery multiplication: returns (x * y) mod Q in Montgomery form


mq18433MontyRed

public int mq18433MontyRed(int x)
Montgomery reduction. The Hawk protocol never feeds x == 0 here (NTT/INTT butterfly products in [1..Q] representation, where Q itself represents 0), but the original short-circuit `if (x == 0) return 0;` is a data-dependent branch on a secret-derived intermediate — replaced with a branchless mask to preserve byte-identity while removing the L1 timing channel.


mq18433Add

public int mq18433Add(int x,
                      int y)
Modular addition: (x + y) mod Q, result in [1..Q] where Q represents 0 mod Q. Matches the C formula:


mq18433Sub

public int mq18433Sub(int x,
                      int y)
Modular subtraction: (x - y) mod Q, result in [1..Q] where Q represents 0 mod Q. Matches the C formula:


mq18433INTT

public void mq18433INTT(int logn,
                        short[] a,
                        int aOffset)
Inverse NTT matching C mq18433_iNTT exactly. 1/n normalization is embedded in the iGM twiddle factors.


mq18433ToMonty

public int mq18433ToMonty(int x)
Convert a number to Montgomery form


mq18433INTTWithScaling

public void mq18433INTTWithScaling(int logn,
                                   short[] a,
                                   int aOffset)
Alias for mq18433INTT kept for compatibility.


mq18433Half

public int mq18433Half(int x)
Compute half: x/2 mod Q. Constant-time: x is a secret-derived INTT butterfly intermediate (each butterfly calls this O(n log n) per signing INTT), so the "is x odd" branch must not be data-dependent. Same pattern as HawkEngine.mpHalf — fold the conditional `+ Q` (only applied when x is odd, to keep the result an integer) into a branchless mask.


mq18433HalfMonty

public int mq18433HalfMonty(int x)
Alternative half implementation using modular inverse of 2


mq18433PolySnorm

public static void mq18433PolySnorm(int logn,
                                    short[] d,
                                    int dOffset)
Apply signed normalization to polynomial coefficients


mq18433Snorm

public static int mq18433Snorm(int x)
Signed normalization: convert to range [-floor((Q-1)/2), floor((Q-1)/2)]. Constant-time: x is a secret-derived NTT coefficient (signing computes f*x1 - g*x0 over secret f, g and sampled x), so the "is x > Q/2" branch must not be data-dependent. We compute a -1/0 mask from the sign of (Q/2 - x) and apply it; byte-identical to the original on all inputs in the polynomial's range.


mq18433SnormSafe

public static int mq18433SnormSafe(int x)
Alternative signed normalization with proper bounds


polySymBreak

public static int polySymBreak(int logn,
                               short[] s,
                               int sOffset)
Returned value: 1 first non-zero coefficient of s is positive -1 first non-zero coefficient of s is negative 0 s is entirely zero


polySymBreakExplicit

public static int polySymBreakExplicit(int logn,
                                       short[] s,
                                       int sOffset)
Alternative implementation with explicit sign detection


encodeSig

public static boolean encodeSig(int logn,
                                byte[] sig,
                                int sigOffset,
                                int sigLen,
                                byte[] salt,
                                int saltOffset,
                                int saltLen,
                                short[] s1,
                                int s1Offset)
Encode the signature, with output length exactly sigLen bytes. Padding is applied if necessary. Returned value is 1 on success, 0 on error; an error is reported if the signature does not fit in the provided buffer.


signFinishInner

public int signFinishInner(int logn,
                           int useShake,
                           byte[] sig,
                           SHAKEDigest scData,
                           byte[] priv,
                           int privLen,
                           byte[] tmp,
                           int tmpLen)

cryptoSign

public int cryptoSign(byte[] sm,
                      long[] smlen,
                      byte[] m,
                      long mlen,
                      byte[] sk,
                      int logn)
Main signing function compatible with the crypto_sign API


sign

public byte[] sign(byte[] message,
                   byte[] privateKey,
                   int logn)
Alternative signature with simpler Java-style API


hawkSignStart

public static void hawkSignStart(SHAKEDigest sc)
Start the signing process - initialize SHAKE context


hawkPrivKeySize

public static int hawkPrivKeySize(int logn)

hawkSigSize

public static int hawkSigSize(int logn)

hawkTmpSizeSign

public static int hawkTmpSizeSign(int logn)

Bouncy Castle Cryptography Library 1.85