Class HawkSigner

    • Constructor Summary

      Constructors 
      Constructor Description
      HawkSigner()  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      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)
      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))
      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
    • 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: d = Q-(x+y); d += Q & (d>>16); return Q-d;
      • 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: d = y-x; d += Q & (d>>16); return Q-d;
      • 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)