diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,257 @@
 # CHANGELOG for crypton
 
+## 2.1.3
+
+* fix(number): the arithmetic crypton falls back to when it is built without
+  GMP no longer walks off the end of a buffer.  `fillPtr` writes a number out
+  starting at its last byte and stops at offset zero, so a number of no bytes
+  -- which is what zero is -- started it at minus one, and it never stopped.
+  The same build also had `exponentiation` fail to terminate on a negative
+  exponent, stepping between -1 and -2 until the stack ran out, where
+  `expFast` and `expSafe` both reach it; `numBits` fail to terminate on a
+  negative number; `numBits 0` answer one where GMP answers zero, so that
+  `numBytes 0` claimed a byte that is not there; and a modulus of one answer
+  one rather than zero in two places.  Every corner is now held to what the
+  GMP build answers on the same input, and `-integer-gmp` has a CI job so
+  that it stays that way
+* fix(cabal): `-fsupport_sse` no longer selects the SSE BLAKE2 and Argon2
+  sources on architectures that have no SSE, where they cannot compile, and
+  `-fold_toolchain_inliner` links again -- one of the sixteen inline
+  definitions in `cbits/decaf/include/word.h` had lost its `static`, which
+  `-fgnu89-inline` turns into a duplicate symbol.  Both flags now have a CI
+  job
+* fix(p256): `crypton_p256_shl` and `crypton_p256_shr` no longer shift a
+  digit by its own width, which the standard leaves undefined and which x86
+  and ARM answer differently.  Nothing in the library calls either, which is
+  why the sanitizers had not reported them: they can only report what runs
+* fix(headers): `crypton_skein256.h` and `crypton_skein512.h` declared six
+  functions under a misspelling of the package's own name, so the six the C
+  defines had no prototype at all.  `crypton_chacha.h` and `crypton_salsa.h`
+  each typedef'd a union to the bare name `block`, so no translation unit
+  could include both; they are `crypton_chacha_block` and
+  `crypton_salsa_block` now
+* security(c): seven places that erase key material and then let the memory
+  die -- five that `memset` a buffer and `free` it on the next line, two that
+  clear a recoded scalar in a local going out of scope -- now write through a
+  volatile pointer, which a compiler may not remove.  clang at -O2 was
+  keeping all seven, but that is its choice rather than a guarantee.  RSA-2048
+  signing is unchanged at 1479.3 microseconds against 1480.0 on an Apple M4
+* perf(ed448): the scalar arithmetic on Apple Silicon runs on 64-bit limbs
+  rather than 32-bit ones.  decaf sized its field limbs from the architecture
+  and its scalar limbs from a macro it worked out from the compiler, and the
+  two disagreed wherever `uint_fast32_t` is four bytes, so the same aarch64
+  CPU took 64-bit field limbs and 32-bit scalar limbs on macOS and 64-bit for
+  both on Linux.  Ed448 signing is 5.5% quicker for it, 20.69 to 19.56
+  microseconds on an M4
+* perf(p256): the one addition in each scalar multiplication that can be a
+  point added to itself goes through a complete formula rather than being
+  detected and worked around.  Kyle Butt pointed out that the comb's table is
+  affine, so the same three numbers are the point in projective coordinates
+  and in Jacobian ones, which is what lets a comb built on Jacobian
+  arithmetic step into the formula for one addition.  It costs about a third
+  of a percent, and buys an argument a reader had to follow becoming a
+  comparison a machine can run
+* doc(hash): the Haddock for `Context` says that it is not erased when it
+  is finished with, what survives in it, and why scrubbing every one is not
+  done -- it costs about 70% of a 32-byte hash, where the allocation is most
+  of the work
+* test(c): the C is now checked in CI for things the test suite cannot ask
+  about: whether it is the same on a 32-bit machine and on a big-endian one,
+  whether a private key ever decides a branch or an address, what a secret
+  leaves behind in memory, and whether anything breaks on generated input.
+  Each of the last four carries a probe that is deliberately wrong and has to
+  be reported, because a check that has quietly stopped working otherwise
+  reads as a clean bill of health -- which, four times over the course of
+  this work, is exactly what it did
+
+* doc(cabal): every dependency has an upper bound, which `cabal check` had
+  been asking for, and `bytestring` is no longer listed twice in the same
+  `build-depends`
+
+* fix(c): the table that says which AES implementation to call is filled in
+  once, before there is a second thread, rather than on every
+  `crypton_aes_initkey`.  Two threads taking a key at the same time were
+  writing the whole table at the same time, which ThreadSanitizer reports
+  forty-four times over for eight threads doing nothing else.  The same for
+  the flags that say whether to use the ARMv8 SHA-1, SHA-256 and SHA-512
+  instructions.  Nothing has ever come of it -- the values written are the
+  same ones every time and the table starts out holding valid generic
+  implementations -- but it is a race the standard gives no meaning to.
+  Taking an AES key is 6.7% quicker for not doing the work again: 72.1 to
+  67.3 nanoseconds on an Apple M4
+* fix(c): the C no longer reads a word off a caller's pointer by casting it,
+  which the standard leaves undefined at an address the word type is not
+  aligned for and which UndefinedBehaviorSanitizer reported on seventy-eight
+  lines.  `crypton_align.h`'s accessors go through `memcpy`, the ten hash
+  implementations read their block a word at a time rather than pointing at
+  it as though it were an array of words, and `block128` is packed so that a
+  caller's pointer may be one.  The non-aligned trampolines those hashes kept
+  for the case are gone with it.  Measured on an Apple M4, every hash and
+  AES-GCM is where it was, within a tenth of a per cent.  The sanitizers now
+  run in CI with nothing turned off
+* fix(c): two left shifts the C standard leaves undefined, found by building
+  the C with UndefinedBehaviorSanitizer and running the test suite.  One
+  shifted a carry into the sign bit of a signed 64-bit digit in
+  `cbits/p256/p256.c`, the other shifted a negative value in
+  `cbits/decaf/ed448goldilocks/decaf.c`.  Neither miscomputes on any compiler
+  crypton is built with, and the values are unchanged; what they were was a
+  licence the standard gives the compiler and no reason to give it
+* security(cipher): a message of 2^32 bytes or more no longer has its length
+  truncated on the way to the C, which takes its lengths as `uint32_t`.  It
+  used to be: `Crypto.Cipher.ChaCha.combine` given 2^32 + 64 bytes enciphered
+  64 of them and returned the rest as it found the buffer -- 4 GiB of zeros
+  where the ciphertext should have been, with nothing returned to say so.
+  `Crypto.Hash` has cut its work into 2 GiB pieces for this reason since
+  before crypton; nothing else did.
+
+  Where the C carries its state in a context and can simply be called again,
+  the work is now cut up the same way and a long message is enciphered:
+  `Crypto.Cipher.ChaCha`, `Crypto.Cipher.Salsa`, `Crypto.Cipher.XSalsa`,
+  `Crypto.Cipher.RC4`, `Crypto.MAC.Poly1305`, and AES-GCM's incremental
+  interface -- which is what `Crypto.Cipher.ChaChaPoly1305` and
+  `Crypto.MAC.KMAC` reach it through.
+
+  Where it cannot -- the one-call AEADs, which do the whole message in one
+  call, and the AES modes, which are handed the IV and do not hand it back --
+  the message is refused: `CryptoError_ParameterInvalid` from
+  `Crypto.Cipher.AES.GCM` and `Crypto.Cipher.ChaCha.Poly1305`, and an error
+  from AES ECB, CBC, CTR, XTS, OCB and CCM.  ECB, CBC and XTS count blocks
+  rather than bytes, so their limit is sixteen times further out.
+  `Crypto.Cipher.AESGCMSIV` already refused, and still does
+* perf(p256): the comb that multiplies the base point takes five bits of the
+  scalar at a time from each of two blocks rather than four, over the signed
+  all-bits-set representation, so the table stays the same size while the
+  loop goes from 32 steps to 26: 25 doublings and 52 mixed additions against
+  31 and 64, which is 19% fewer field operations.  An ECDSA P-256 signature
+  goes 25.52 to 22.47 microseconds on an Apple M4.  This is the C path, which
+  x86-64 and AArch64 do not take -- they have the vendored assembly -- so it
+  is for i386, armv7, riscv64, ppc64le, s390x and the rest.  The arrangement
+  was suggested by Kyle Butt.
+
+  One scalar below the order makes the last addition of the comb add a point
+  to itself, which the formulas there cannot do; it was found by searching
+  the sign patterns rather than by sampling, and the recoder now reports it
+  and the answer is the doubling.  Every other addition is ruled out, the 48
+  from step two upwards by parity and size and the two of step one by
+  exhausting the 2^20 sign patterns that could reach them
+* security(aes): `Crypto.Cipher.AES.GCM` refuses a nonce of no bytes, which
+  its four functions used to accept.  SP 800-38D 5.2.1.1 asks for at least
+  one byte, and with none GCM's pre-counter block is zero, so the tag of a
+  message is `GHASH_H(A, C) XOR E(K, 0^128)` -- and `E(K, 0^128)` is the
+  GHASH key `H` itself.  One full tag therefore gives `H` away; `H` belongs
+  to the key rather than to the nonce, so an attacker who has it, and one
+  genuine message under any nonce, can forge a tag that verifies for data of
+  their own under that nonce, twelve-byte ones included.  `encrypt` and
+  `decryptWithTag` now throw `CryptoError_IvSizeInvalid`, `decrypt` gives
+  `Nothing` and `encryptWithMask` gives `False` and writes nothing.  Only the
+  empty nonce is refused; every other length stays allowed.  The general
+  interface has refused it since 2.1.0 and this module did not.  Affects
+  2.1.0, 2.1.1 and 2.1.2.  Reported by arybczak in
+  [#249](https://github.com/kazu-yamamoto/crypton/issues/249)
+* perf(rsa): the multiply-accumulate at the bottom of the modular
+  exponentiation takes four limbs to an iteration on AArch64, with the flags
+  carrying through two long chains -- one for the low halves of the four
+  products, one for the high halves a place up -- where the compiler writes
+  a chain per limb and spends two instructions moving each carry between the
+  flags and a register.  Measured on an Apple M4, an RSA-2048 signature goes
+  593.0 to 515.9 microseconds through the Haskell API and the exponentiation
+  itself 590.1 to 514.9.  The ragged end of a row -- three limbs, two or
+  one -- is written out the same way rather than handed back to C, which
+  matters because mont_sqr asks for every length from n-1 down to 1: that is
+  a further two per cent of the exponentiation, 514.2 to 504.9.  The
+  arrangement follows addMulVVWx in Go's crypto/internal/fips140/bigmod,
+  which is BSD-3-Clause as this library is; cbits/LICENSE.go carries its
+  notice.  Three other arrangements were tried and measured worse, and the
+  comment above the function says which and why, so that they are not tried
+  again
+* perf(rsa): a Montgomery multiplication no longer clears its 2n-limb
+  scratch first.  The first row of the product lands on empty space, so it
+  is written rather than added to, and every row after it reads only limbs
+  an earlier row has already put there.  Worth between a half and one per
+  cent of an RSA-2048 signature on an Apple M4, which is less than it
+  sounds like it should be: the clearing was cheap, and what it cost was
+  mostly the row that had to add to zeros
+* perf(rsa): the R^2 that Montgomery arithmetic needs before it can start is
+  built by squaring rather than by doubling a bit at a time.  Write a value
+  as 2^(lgR + d) mod m; a Montgomery squaring divides by R, so it takes that
+  to 2^(lgR + 2d) and doubles d.  The climb from R to R^2 is then the binary
+  expansion of lgR -- ten squarings for a 1024-bit modulus, where there were
+  a thousand and twenty-five doublings.  On an Apple M4 the setup goes 24.74
+  to 2.07 microseconds, and an RSA-2048 signature does it twice, once for
+  each CRT half: the signature goes 512.3 to 466.9 through the Haskell API
+  and the two exponentiations 502.6 to 457.0.  Curves that go through
+  crypton_ecc.c pay the same setup once per context and gain the same.
+  Public-key operations still go through GMP and do not change
+* perf(ecdsa): P-256 verification multiplies both scalars at once, in
+  variable time, where it used to do two constant-time multiplications and
+  add the results.  Everything a verification touches is public -- the
+  message, the signature and the public key -- so the constant-time work
+  there was paid for nothing, and the two multiplications can share their
+  doublings besides.  Both scalars go into non-adjacent form, width 7 for
+  the base point, whose odd multiples are a table in the library, and width
+  5 for the public key, whose eight are built per call; one pass down the
+  digits does a doubling at every step and an addition where a digit is not
+  zero.  Measured through the Haskell API on an Apple M4, a verification
+  goes 30.37 to 25.48 microseconds, and the multiplication itself 29.94 to
+  25.34; on an x86-64, 85.04 to 71.53.  Signing is untouched.  s2n-bignum's
+  point addition is correct except when its two arguments are the same
+  point, which is the side condition its proof carries, so a sum that comes
+  out as the point at infinity from arguments that were not is given up on
+  and the constant-time pair answers instead -- 1203 cases covering that,
+  including 41 that take the fallback, agree with the old answers on both
+  architectures
+* perf(gcm): AES-GCM uses the 512-bit form of the AES and carry-less
+  multiply instructions where the processor has them and they are worth
+  having, which is Ice Lake and Zen 5 onwards.  Four blocks to an
+  instruction where the 256-bit form takes two; a group is thirty-two
+  blocks in eight registers and its GHASH is two passes of sixteen, since
+  sixteen is how many powers of H the table holds.  Measured on GitHub's
+  runners over 16 KiB, AES-128-GCM and AES-256-GCM in MB/s: an EPYC 9V45
+  goes 9616 to 14268 and 8422 to 12674, a Xeon 6973P-C 8095 to 9848 and
+  7187 to 8323, a Xeon 8573C 6983 to 8447 and 6166 to 7113.  Zen 4 is left
+  on the 256-bit path -- there the 512-bit instructions are two passes
+  through a 256-bit datapath, and AES-GCM measured slightly slower -- and
+  the run-time check asks for three more bits of XCR0 as well as the
+  instruction bits, since a machine can report these and still fault on
+  them
+* perf(ed25519): the base point multiplication goes through s2n-bignum,
+  which signing does twice -- once for the nonce's point and once for the
+  public key, which `sign` derives from the secret key every time rather
+  than trusting the one it is handed.  Measured through the Haskell API on
+  an Apple M4, signing goes 11.92 to 7.27 microseconds and `toPublic` 5.97
+  to 3.52; at the C level on an x86-64 without ADX, where the `_alt` form
+  runs, a public key goes 13.25 to 9.93 and a signature with the key in
+  hand 14.74 to 11.34.  Verification is untouched: it multiplies two
+  scalars at once and crypton's variable-time code is ahead of the
+  constant-time assembly there.  ed25519-donna's table stays for every
+  other architecture, and 5000 key and signature pairs agree between the
+  two paths on both architectures
+* perf(rsa): the masked scan of the exponentiation's table goes four limbs
+  at a time on x86-64 with AVX2.  Every entry of the table is read and a
+  mask keeps the one the window asks for, which is what keeps the address
+  stream off the exponent, and at RSA-2048's CRT size that is two kilobytes
+  read per window with 256 windows to an exponentiation -- 11% of the whole
+  where s2n-bignum's multiplication runs, measured by taking the scan out
+  altogether.  With the vector form almost all of it comes back: one
+  RSA-2048 CRT private operation goes 812.4 to 720.8 microseconds against a
+  707.1 floor with no scan at all, and on the same machine without ADX
+  1646.1 to 1599.3.  AArch64 keeps the scalar form, where the same
+  measurement puts the scan at 1% and there is nothing to win.  The
+  processor is asked once per call, and without the AVX2 bit, or built
+  without `use_target_attributes`, the scalar scan is what runs
+* perf(rsa): the modular exponentiation squares into the other of its two
+  buffers and swaps them, rather than squaring into one and copying it back.
+  That is a copy of the modulus' width saved 1280 times per exponentiation,
+  and which of the three buffers a pointer names is nobody's secret, so
+  nothing about the timing changes.  Measured by thread CPU time, best of
+  many, on one RSA-2048 CRT private operation: an Apple M4 goes 604.3 to
+  595.9 microseconds and an x86-64 without ADX 1678.0 to 1665.6.  Where
+  s2n-bignum's multiplication runs the difference is below the noise, that
+  multiplication being most of the time there.  Also writes down what a
+  five-bit window is worth, which was measured and is not taken: 3.5% on the
+  M4, 1% the wrong way on an older x86-64, and 7% the wrong way wherever the
+  assembly runs, because a table twice as long is a masked scan twice as long
+
 ## 2.1.2
 
 * perf(gcm): AES-GCM uses the 256-bit form of the AES and carry-less
diff --git a/Crypto/Cipher/AES/GCM.hs b/Crypto/Cipher/AES/GCM.hs
--- a/Crypto/Cipher/AES/GCM.hs
+++ b/Crypto/Cipher/AES/GCM.hs
@@ -59,6 +59,7 @@
     initAES,
  )
 import Crypto.Cipher.Types (AuthTag)
+import Crypto.Cipher.Types.AEAD (minimumTagLength)
 import Crypto.Error
 import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess)
 import qualified Crypto.Internal.ByteArray as B
@@ -79,13 +80,17 @@
 
 -- | Encrypt one message: the nonce, the additional data that is
 -- authenticated but not encrypted, the plaintext, and how many bytes of tag
--- to produce, which GCM allows between 4 and 16.
+-- to produce, which GCM allows between 4 and 16.  Any other length throws
+-- 'CryptoError_AuthenticationTagSizeInvalid', and so does 'decryptWithTag'.
 --
 -- The answer is the ciphertext followed by the tag.
 --
 -- A nonce must not be used twice with the same t'Context'.  Twelve bytes is
 -- the size GCM is defined for and the only one that does not cost a further
--- pass.
+-- pass.  A nonce of no bytes is refused: it would hand out the key GCM
+-- authenticates with, so 'encrypt' and 'decryptWithTag' throw
+-- 'CryptoError_IvSizeInvalid' for it, 'decrypt' gives 'Nothing' and
+-- 'encryptWithMask' gives 'False'.
 {-# INLINABLE encrypt #-}
 encrypt
     :: ( ByteArrayAccess nonce
@@ -99,15 +104,22 @@
     -> ba
     -> Int
     -> output
-encrypt (Context aes gk) nonce aad input taglen =
-    gcmFullEncrypt aes gk nonce aad input taglen
+encrypt (Context aes gk) nonce aad input taglen
+    | tooLongForC aad input =
+        throwCryptoError (CryptoFailed CryptoError_ParameterInvalid)
+    | badNonce nonce =
+        throwCryptoError (CryptoFailed CryptoError_IvSizeInvalid)
+    | badTagLength taglen =
+        throwCryptoError (CryptoFailed CryptoError_AuthenticationTagSizeInvalid)
+    | otherwise = gcmFullEncrypt aes gk nonce aad input taglen
 
 -- | Decrypt one message, in the shape 'encrypt' produced: the ciphertext with
 -- its tag after it.  The tag is compared here, every byte of it whatever the
 -- answer, and a message whose tag does not match gives 'Nothing' rather than
 -- the plaintext.
 --
--- 'Nothing' also comes back when the input is shorter than the tag.
+-- 'Nothing' also comes back when the nonce has no bytes, the input is
+-- shorter than the tag, or the tag length is outside 4 to 16.
 {-# INLINABLE decrypt #-}
 decrypt
     :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArray ba)
@@ -118,7 +130,8 @@
     -> Int
     -> Maybe ba
 decrypt (Context aes gk) nonce aad input taglen
-    | taglen < 0 || B.length input < taglen = Nothing
+    | tooLongForC aad input = Nothing
+    | badNonce nonce || badTagLength taglen || B.length input < taglen = Nothing
     | otherwise = gcmFullDecrypt aes gk nonce aad body tag
   where
     (body, tag) = B.splitAt (B.length input - taglen) input
@@ -144,8 +157,14 @@
     -> ba
     -> Int
     -> (ba, AuthTag)
-decryptWithTag (Context aes gk) nonce aad input taglen =
-    gcmFullDecryptTag aes gk nonce aad input taglen
+decryptWithTag (Context aes gk) nonce aad input taglen
+    | tooLongForC aad input =
+        throwCryptoError (CryptoFailed CryptoError_ParameterInvalid)
+    | badNonce nonce =
+        throwCryptoError (CryptoFailed CryptoError_IvSizeInvalid)
+    | badTagLength taglen =
+        throwCryptoError (CryptoFailed CryptoError_AuthenticationTagSizeInvalid)
+    | otherwise = gcmFullDecryptTag aes gk nonce aad input taglen
 
 ----------------------------------------------------------------
 
@@ -170,7 +189,8 @@
 -- sixteen.  @sampleOffset@ says where the sixteen bytes of sample begin in
 -- the sealed message, counting the tag as part of it.
 --
--- 'False' comes back, and nothing is written, when the sample would not fit.
+-- 'False' comes back, and nothing is written, when the nonce has no bytes,
+-- the sample would not fit, or the tag length is outside 4 to 16.
 {-# INLINABLE encryptWithMask #-}
 encryptWithMask
     :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArrayAccess ba)
@@ -189,7 +209,48 @@
     -- ^ where the sixteen bytes of mask go
     -> IO Bool
 encryptWithMask (Context aes gk) (HeaderKey hp) nonce aad input taglen off outp maskp
-    | off < 0 || taglen < 0 || off + 16 > B.length input + taglen = return False
+    | tooLongForC aad input = return False
+    | badNonce nonce = return False
+    | off < 0 || badTagLength taglen || off + 16 > B.length input + taglen =
+        return False
     | otherwise = do
         gcmFullEncryptMask aes gk hp nonce aad input taglen off outp maskp
         return True
+
+-- | The C behind all four takes its lengths as @uint32_t@, so a message or
+-- its additional data from 2^32 bytes up cannot be handed to it: the length
+-- would be truncated and most of the buffer left untouched, with nothing to
+-- say so.  There is no splitting the work here -- the C does the whole
+-- message in one call, tag and all -- so such a message is refused.
+tooLongForC
+    :: (ByteArrayAccess aad, ByteArrayAccess ba) => aad -> ba -> Bool
+tooLongForC aad input =
+    B.overCLength (B.length aad) || B.overCLength (B.length input)
+
+-- | SP 800-38D 5.2.1.1 asks for at least one byte of IV, and this is why.
+--
+-- GCM builds its pre-counter block from a nonce that is not twelve bytes as
+-- @J0 = GHASH_H(IV || 0^s || [0]_64 || [len(IV)]_64)@.  For an empty IV that
+-- input is one block of zeros, so @J0@ is zero, and the tag of a message
+-- becomes @GHASH_H(A, C) XOR E(K, 0^128)@ -- where @E(K, 0^128)@ is the
+-- definition of @H@.  The tag of an empty message under an empty nonce is
+-- therefore @H@ itself, and any other full tag gives @H@ as the root of a
+-- known polynomial.
+--
+-- @H@ belongs to the key, not to the nonce.  An attacker holding it, plus one
+-- genuine message under any nonce, has @E(K, J0)@ for that nonce and can make
+-- a tag that verifies for data of their own -- under a correct twelve-byte
+-- nonce, and for every nonce they have seen.  One encryption with an empty
+-- nonce and a full tag ends the authenticity of everything under the key.
+--
+-- 'Crypto.Cipher.AES.Primitive.gcmAeadInit' refuses the empty IV for this
+-- reason, and these four have to as well.  Only the empty one is refused:
+-- SP 800-38D allows every length from one byte up.
+badNonce :: ByteArrayAccess nonce => nonce -> Bool
+badNonce nonce = B.length nonce == 0
+
+-- | GCM makes a sixteen-byte tag and a shorter one is a prefix of it.  Below
+-- 'minimumTagLength' it authenticates next to nothing, and past sixteen the
+-- C code would read beyond the tag it computed.
+badTagLength :: Int -> Bool
+badTagLength t = t < minimumTagLength || t > 16
diff --git a/Crypto/Cipher/AES/Primitive.hs b/Crypto/Cipher/AES/Primitive.hs
--- a/Crypto/Cipher/AES/Primitive.hs
+++ b/Crypto/Cipher/AES/Primitive.hs
@@ -271,6 +271,7 @@
     -- ^ ciphertext output
 encryptCTR ctx iv input
     | len <= 0 = B.empty
+    | B.overCLength len = error tooLongMessage
     | B.length iv /= 16 =
         error $
             "AES error: IV length must be block size (16). Its length is: "
@@ -365,6 +366,20 @@
         c_aes_encrypt_c32 (castPtr o) k v i (fromIntegral len)
     len = B.length input
 
+-- | What the AES modes say when a message cannot be given to the C, whose
+-- lengths are @uint32_t@.  Above that the length is truncated on the way
+-- down and most of the buffer is left as it was found, with nothing to say
+-- so, which is worse than refusing.
+--
+-- Unlike the stream ciphers, these cannot be done in pieces: the C is handed
+-- the IV and does not hand it back, so a second call would start from the
+-- wrong place.  ECB, CBC and XTS count blocks rather than bytes, so their
+-- limit is sixteen times further out than CTR's.
+tooLongMessage :: String
+tooLongMessage =
+    "AES error: message too long for this implementation, whose C takes its "
+        ++ "lengths as uint32_t"
+
 {-# INLINE doECB #-}
 doECB
     :: ByteArray ba
@@ -373,6 +388,7 @@
     -> ba
     -> ba
 doECB f ctx input
+    | B.overCLength nbBlocks = error tooLongMessage
     | len == 0 = B.empty
     | r /= 0 =
         error $
@@ -396,6 +412,7 @@
     -> ba
     -> ba
 doCBC f ctx (IV iv) input
+    | B.overCLength nbBlocks = error tooLongMessage
     | len == 0 = B.empty
     | r /= 0 =
         error $
@@ -419,6 +436,7 @@
     -> ba
     -> ba
 doXTS f (key1, key2) iv spoint input
+    | B.overCLength nbBlocks = error tooLongMessage
     | len == 0 = B.empty
     | r /= 0 =
         error $
@@ -637,7 +655,8 @@
     doAppend =
         withNewGCMSt gcmSt $ \gcmStPtr ->
             withByteArray input $ \i ->
-                c_aes_gcm_aad gcmStPtr i (fromIntegral $ B.length input)
+                B.inCLengths (B.length input) $ \off n ->
+                    c_aes_gcm_aad gcmStPtr (i `plusPtr` off) (fromIntegral n)
 
 -- | append data to encrypt and append to the GCM context
 --
@@ -651,7 +670,13 @@
     doEnc gcmStPtr aesPtr =
         B.alloc len $ \o ->
             withByteArray input $ \i ->
-                c_aes_gcm_encrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len)
+                B.inCLengths len $ \off n ->
+                    c_aes_gcm_encrypt
+                        (castPtr o `plusPtr` off)
+                        gcmStPtr
+                        aesPtr
+                        (i `plusPtr` off)
+                        (fromIntegral n)
 
 -- | append data to decrypt and append to the GCM context
 --
@@ -665,7 +690,13 @@
     doDec gcmStPtr aesPtr =
         B.alloc len $ \o ->
             withByteArray input $ \i ->
-                c_aes_gcm_decrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len)
+                B.inCLengths len $ \off n ->
+                    c_aes_gcm_decrypt
+                        (castPtr o `plusPtr` off)
+                        gcmStPtr
+                        aesPtr
+                        (i `plusPtr` off)
+                        (fromIntegral n)
 
 -- | Generate the Tag from GCM context
 {-# NOINLINE gcmFinish #-}
@@ -722,7 +753,9 @@
 -- need to happen after initialization and before appending encryption/decryption data.
 {-# NOINLINE ocbAppendAAD #-}
 ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
-ocbAppendAAD ctx ocb input = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend)
+ocbAppendAAD ctx ocb input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend)
   where
     doAppend ocbStPtr aesPtr =
         withByteArray input $ \i ->
@@ -734,7 +767,9 @@
 -- need to happen after AAD appending, or after initialization if no AAD data.
 {-# NOINLINE ocbAppendEncrypt #-}
 ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
-ocbAppendEncrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc
+ocbAppendEncrypt ctx ocb input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc
   where
     len = B.length input
     doEnc ocbStPtr aesPtr =
@@ -748,7 +783,9 @@
 -- need to happen after AAD appending, or after initialization if no AAD data.
 {-# NOINLINE ocbAppendDecrypt #-}
 ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
-ocbAppendDecrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doDec
+ocbAppendDecrypt ctx ocb input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doDec
   where
     len = B.length input
     doDec ocbStPtr aesPtr =
@@ -808,7 +845,9 @@
 -- needs to happen after initialization and before appending encryption/decryption data.
 {-# NOINLINE ccmAppendAAD #-}
 ccmAppendAAD :: ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM
-ccmAppendAAD ctx ccm input = unsafeDoIO $ snd <$> withCCMKeyAndCopySt ctx ccm doAppend
+ccmAppendAAD ctx ccm input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO $ snd <$> withCCMKeyAndCopySt ctx ccm doAppend
   where
     doAppend ccmStPtr aesPtr =
         withByteArray input $ \i -> c_aes_ccm_aad ccmStPtr aesPtr i (fromIntegral $ B.length input)
@@ -819,7 +858,9 @@
 -- needs to happen after AAD appending, or after initialization if no AAD data.
 {-# NOINLINE ccmEncrypt #-}
 ccmEncrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
-ccmEncrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
+ccmEncrypt ctx ccm input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
   where
     len = B.length input
     cbcmacAndIv ccmStPtr aesPtr =
@@ -833,7 +874,9 @@
 -- needs to happen after AAD appending, or after initialization if no AAD data.
 {-# NOINLINE ccmDecrypt #-}
 ccmDecrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
-ccmDecrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
+ccmDecrypt ctx ccm input
+    | B.overCLength (B.length input) = error tooLongMessage
+    | otherwise = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
   where
     len = B.length input
     cbcmacAndIv ccmStPtr aesPtr =
diff --git a/Crypto/Cipher/ChaCha.hs b/Crypto/Cipher/ChaCha.hs
--- a/Crypto/Cipher/ChaCha.hs
+++ b/Crypto/Cipher/ChaCha.hs
@@ -183,10 +183,19 @@
     | B.null src = (B.empty, prevSt)
     | otherwise = unsafeDoIO $ do
         (out, st) <- B.copyRet prevStMem $ \ctx ->
-            B.alloc (B.length src) $ \dstPtr ->
+            B.alloc n $ \dstPtr ->
                 B.withByteArray src $ \srcPtr ->
-                    ccrypton_chacha_combine dstPtr ctx srcPtr (fromIntegral $ B.length src)
+                    -- in pieces the C's uint32_t length can hold; it carries
+                    -- the state in ctx, so it can simply be called again
+                    B.inCLengths n $ \off len ->
+                        ccrypton_chacha_combine
+                            (dstPtr `plusPtr` off)
+                            ctx
+                            (srcPtr `plusPtr` off)
+                            (fromIntegral len)
         return (out, State st)
+  where
+    n = B.length src
 
 -- | Generate a number of bytes from the ChaCha output directly
 generate
@@ -201,7 +210,11 @@
     | otherwise = unsafeDoIO $ do
         (out, st) <- B.copyRet prevStMem $ \ctx ->
             B.alloc len $ \dstPtr ->
-                ccrypton_chacha_generate dstPtr ctx (fromIntegral len)
+                B.inCLengths len $ \off n ->
+                    ccrypton_chacha_generate
+                        (dstPtr `plusPtr` off)
+                        ctx
+                        (fromIntegral n)
         return (out, State st)
 
 -- | similar to 'generate' but assume certains values
diff --git a/Crypto/Cipher/ChaCha/Poly1305.hs b/Crypto/Cipher/ChaCha/Poly1305.hs
--- a/Crypto/Cipher/ChaCha/Poly1305.hs
+++ b/Crypto/Cipher/ChaCha/Poly1305.hs
@@ -31,7 +31,6 @@
 import qualified Crypto.Internal.ByteArray as B
 import Crypto.Internal.Compat (unsafeDoIO)
 import Crypto.Internal.Imports
-import Data.Word (Word8)
 import Foreign.C.Types (CInt (..), CUInt (..))
 import Foreign.Ptr (Ptr, plusPtr)
 
@@ -58,7 +57,7 @@
 -- which is the shape 'decrypt' expects.
 --
 -- The nonce is the twelve bytes RFC 8439 defines; any other length gives
--- 'CryptoError_IvSizeInvalid'.  The tag is at most 16 bytes.
+-- 'CryptoError_IvSizeInvalid'.  RFC 8439 requires a 16-byte tag.
 {-# INLINABLE encrypt #-}
 encrypt
     :: ( ByteArrayAccess nonce
@@ -73,6 +72,7 @@
     -> Int
     -> CryptoFailable output
 encrypt (Context k) nonce aad input taglen
+    | tooLongForC aad input = CryptoFailed CryptoError_ParameterInvalid
     | not (validNonce nonce) = CryptoFailed CryptoError_IvSizeInvalid
     | badTag taglen = CryptoFailed CryptoError_AuthenticationTagSizeInvalid
     | otherwise =
@@ -112,6 +112,7 @@
     -> Int
     -> Maybe ba
 decrypt (Context k) nonce aad input taglen
+    | tooLongForC aad input = Nothing
     | not (validNonce nonce) = Nothing
     | badTag taglen || B.length input < taglen = Nothing
     | otherwise = unsafeDoIO $ do
@@ -159,6 +160,7 @@
     -> Int
     -> CryptoFailable (ba, AuthTag)
 decryptWithTag (Context k) nonce aad input taglen
+    | tooLongForC aad input = CryptoFailed CryptoError_ParameterInvalid
     | not (validNonce nonce) = CryptoFailed CryptoError_IvSizeInvalid
     | badTag taglen = CryptoFailed CryptoError_AuthenticationTagSizeInvalid
     | otherwise = CryptoPassed $ unsafeDoIO $ do
@@ -181,6 +183,15 @@
                                     (fromIntegral $ B.length input)
         return (out, AuthTag $ B.convert (tagbs :: B.Bytes))
 
+-- | The C takes its lengths as @uint32_t@, so a message or its additional
+-- data from 2^32 bytes up cannot be handed to it: the length would be
+-- truncated and most of the buffer left untouched, with nothing to say so.
+-- The C does the whole message in one call, so there is no splitting it.
+tooLongForC
+    :: (ByteArrayAccess aad, ByteArrayAccess ba) => aad -> ba -> Bool
+tooLongForC aad input =
+    B.overCLength (B.length aad) || B.overCLength (B.length input)
+
 -- RFC 8439 is the twelve-byte nonce.  ChaCha20 will take eight, but that is
 -- the other construction, with a 64-bit block counter, and it is not what
 -- this AEAD is defined over -- so it is refused here rather than quietly
@@ -189,7 +200,7 @@
 validNonce n = B.length n == 12
 
 badTag :: Int -> Bool
-badTag t = t < 0 || t > 16
+badTag t = t /= 16
 
 -- | An unsafe call keeps a capability for as long as it runs, so it is only
 -- for a message short enough that the run is short.  Four kibibytes is what
diff --git a/Crypto/Cipher/RC4.hs b/Crypto/Cipher/RC4.hs
--- a/Crypto/Cipher/RC4.hs
+++ b/Crypto/Cipher/RC4.hs
@@ -98,7 +98,14 @@
     B.allocRet len $ \outptr ->
         B.withByteArray clearText $ \clearPtr -> do
             st <- B.copy prevSt $ \stPtr ->
-                c_rc4_combine (castPtr stPtr) clearPtr (fromIntegral len) outptr
+                -- in pieces the C's uint32_t length can hold; the state it
+                -- keeps means it can simply be called again
+                B.inCLengths len $ \off n ->
+                    c_rc4_combine
+                        (castPtr stPtr)
+                        (clearPtr `plusPtr` off)
+                        (fromIntegral n)
+                        (outptr `plusPtr` off)
             return $! State st
   where
     -- return $! (State st, B.PS outfptr 0 len)
diff --git a/Crypto/Cipher/Salsa.hs b/Crypto/Cipher/Salsa.hs
--- a/Crypto/Cipher/Salsa.hs
+++ b/Crypto/Cipher/Salsa.hs
@@ -70,10 +70,19 @@
     | B.null src = (B.empty, prevSt)
     | otherwise = unsafeDoIO $ do
         (out, st) <- B.copyRet prevStMem $ \ctx ->
-            B.alloc (B.length src) $ \dstPtr ->
-                B.withByteArray src $ \srcPtr -> do
-                    ccrypton_salsa_combine dstPtr ctx srcPtr (fromIntegral $ B.length src)
+            B.alloc n $ \dstPtr ->
+                B.withByteArray src $ \srcPtr ->
+                    -- in pieces the C's uint32_t length can hold; it carries
+                    -- the state in ctx, so it can simply be called again
+                    B.inCLengths n $ \off len ->
+                        ccrypton_salsa_combine
+                            (dstPtr `plusPtr` off)
+                            ctx
+                            (srcPtr `plusPtr` off)
+                            (fromIntegral len)
         return (out, State st)
+  where
+    n = B.length src
 
 -- | Generate a number of bytes from the Salsa output directly
 generate
@@ -88,7 +97,11 @@
     | otherwise = unsafeDoIO $ do
         (out, st) <- B.copyRet prevStMem $ \ctx ->
             B.alloc len $ \dstPtr ->
-                ccrypton_salsa_generate dstPtr ctx (fromIntegral len)
+                B.inCLengths len $ \off n ->
+                    ccrypton_salsa_generate
+                        (dstPtr `plusPtr` off)
+                        ctx
+                        (fromIntegral n)
         return (out, State st)
 
 foreign import ccall "crypton_salsa_init"
diff --git a/Crypto/Hash/Types.hs b/Crypto/Hash/Types.hs
--- a/Crypto/Hash/Types.hs
+++ b/Crypto/Hash/Types.hs
@@ -103,6 +103,26 @@
 -- layout is architecture dependent, may contain uninitialized data fragments,
 -- and change in future versions.  The bytearray should not be used as input to
 -- cryptographic algorithms.
+--
+-- __A context is not erased when it is finished with.__  A hash algorithm
+-- buffers its input a block at a time, and finalizing does not clear what is
+-- left there.  How much survives depends on where the message ended relative
+-- to the block: with SHA-256, a 32-byte message is still in the context in
+-- full afterwards, and a 100-byte one leaves its last 36 bytes.
+-- @hashFinalize@ works on a copy, so the caller's own context keeps what it
+-- had as well.  Nothing clears either of them: this is 'Bytes' rather than
+-- @ScrubbedBytes@, and the C clears nothing.  They go to the garbage
+-- collector as they are, and a core file, a crash dump or a swapped page can
+-- carry them away afterwards.
+--
+-- That is a deliberate trade rather than an oversight, and there is no way
+-- to ask for the other side of it: no operation here clears a context.
+-- Scrubbing them all was measured at about 70% of a 32-byte hash and a third
+-- of an incremental one, because the allocation is most of the work when the
+-- message is short -- and short hashes are the common case, in HMAC, in
+-- HKDF, and anywhere a key or an identifier is hashed.  A 64 KB hash does
+-- not notice it.  Anything that must not be left in memory this way is
+-- better not hashed through this interface at all.
 newtype Context a = Context Bytes
     deriving (ByteArrayAccess, NFData)
 
diff --git a/Crypto/Internal/ByteArray.hs b/Crypto/Internal/ByteArray.hs
--- a/Crypto/Internal/ByteArray.hs
+++ b/Crypto/Internal/ByteArray.hs
@@ -14,6 +14,8 @@
     module Data.ByteArray.Mapping,
     module Data.ByteArray.Encoding,
     constAllZero,
+    overCLength,
+    inCLengths,
     allocAndFreezePrimIO,
     allocAndFreezePrim,
     bxor,
@@ -30,6 +32,51 @@
 import Foreign.Storable (peekByteOff)
 
 import Crypto.Internal.Compat (unsafeDoIO)
+
+-- | Whether a length is too large to reach the C, which takes its lengths as
+-- @uint32_t@.
+--
+-- From 2^32 up the value is truncated on the way down, and the C then works
+-- on the low bits of it and leaves the rest of the buffer as it found it --
+-- which for a fresh allocation is zeros.  What comes back is as long as the
+-- caller asked for, with nothing to say that most of it was never written:
+-- a 4 GiB message through Crypto.Cipher.ChaCha.combine came back with 2^32
+-- bytes of zeros where the ciphertext should have been.
+--
+-- Every place that hands a caller's length to the C either turns it away
+-- with this or cuts the work into pieces small enough to pass.
+--
+-- The round trip through 'Word32' rather than a comparison against 2^32,
+-- which a 32-bit 'Int' cannot hold.  There every non-negative 'Int' passes,
+-- which is the right answer: there is no such buffer to be had.
+overCLength :: Int -> Bool
+overCLength n = fromIntegral (fromIntegral n :: Word32) /= n
+
+-- | Walk a length in pieces small enough to reach the C, calling the action
+-- with the offset and the size of each.
+--
+-- The same 2 GiB step "Crypto.Hash" has always taken, and for the same
+-- reason: the C takes its lengths as @uint32_t@, and a 32-bit 'Int' cannot
+-- hold a whole one either.  This is for the C that keeps its state in a
+-- context and can simply be called again -- the stream ciphers, the MACs --
+-- where a long message can be enciphered in pieces rather than refused.
+inCLengths :: Int -> (Int -> Int -> IO ()) -> IO ()
+inCLengths total f = go 0
+  where
+    go !off
+        | off >= total = return ()
+        | otherwise = f off n >> go (off + n)
+      where
+        !n = min (total - off) cChunk
+
+-- | The step 'inCLengths' takes: the largest multiple of 64 that a signed
+-- 32-bit integer holds.
+--
+-- Under 2^31 because a 32-bit 'Int' cannot hold more, and a
+-- multiple of 64 because some of the C this feeds -- the AEAD modes -- will
+-- take a piece that is not a whole number of blocks only as the last one.
+cChunk :: Int
+cChunk = 0x7fffffc0
 
 -- | Allocate a pinned 'Prim.ByteArray' of the given size, populate it via a
 -- 'Ptr', then freeze and return it.  The pointer must not be retained after
diff --git a/Crypto/MAC/Poly1305.hs b/Crypto/MAC/Poly1305.hs
--- a/Crypto/MAC/Poly1305.hs
+++ b/Crypto/MAC/Poly1305.hs
@@ -92,7 +92,10 @@
 update :: ByteArrayAccess ba => State -> ba -> State
 update (State prevCtx) d = State $ B.copyAndFreeze prevCtx $ \ctxPtr ->
     B.withByteArray d $ \dataPtr ->
-        c_poly1305_update (castPtr ctxPtr) dataPtr (fromIntegral $ B.length d)
+        -- in pieces the C's uint32_t length can hold; the context carries
+        -- across, so it can simply be called again
+        B.inCLengths (B.length d) $ \off n ->
+            c_poly1305_update (castPtr ctxPtr) (dataPtr `plusPtr` off) (fromIntegral n)
 {-# NOINLINE update #-}
 
 -- | updates a context with multiples bytestring
@@ -101,7 +104,9 @@
   where
     loop [] _ = return ()
     loop (x : xs) ctxPtr = do
-        B.withByteArray x $ \dataPtr -> c_poly1305_update ctxPtr dataPtr (fromIntegral $ B.length x)
+        B.withByteArray x $ \dataPtr ->
+            B.inCLengths (B.length x) $ \off n ->
+                c_poly1305_update ctxPtr (dataPtr `plusPtr` off) (fromIntegral n)
         loop xs ctxPtr
 {-# NOINLINE updates #-}
 
@@ -124,5 +129,9 @@
         B.withByteArray k $ \keyPtr -> do
             c_poly1305_init (castPtr ctxPtr) keyPtr
             B.withByteArray d $ \dataPtr ->
-                c_poly1305_update (castPtr ctxPtr) dataPtr (fromIntegral $ B.length d)
+                B.inCLengths (B.length d) $ \off n ->
+                    c_poly1305_update
+                        (castPtr ctxPtr)
+                        (dataPtr `plusPtr` off)
+                        (fromIntegral n)
             c_poly1305_finalize dst (castPtr ctxPtr)
diff --git a/Crypto/Number/Basic.hs b/Crypto/Number/Basic.hs
--- a/Crypto/Number/Basic.hs
+++ b/Crypto/Number/Basic.hs
@@ -85,7 +85,12 @@
 
 -- | Compute the number of bits for an integer
 numBits :: Integer -> Int
-numBits n = gmpSizeInBits n `onGmpUnsupported` (if n == 0 then 1 else computeBits 0 n)
+-- GMP sizes the magnitude and calls zero zero bits, and every caller here --
+-- 'numBytes' above all -- is written against that.  The fallback used to
+-- answer 1 for zero, and to divide a negative number by 256 forever, because
+-- the quotient never reaches zero.
+numBits n =
+    gmpSizeInBits n `onGmpUnsupported` (if n == 0 then 0 else computeBits 0 (abs n))
   where
     computeBits !acc i
         | q == 0 =
diff --git a/Crypto/Number/ModArithmetic.hs b/Crypto/Number/ModArithmetic.hs
--- a/Crypto/Number/ModArithmetic.hs
+++ b/Crypto/Number/ModArithmetic.hs
@@ -171,9 +171,19 @@
 
 -- | @exponentiation@ computes modular exponentiation as /b^e mod m/
 -- using repetitive squaring.
+--
+-- The corner cases are held to what GMP answers, since that is what this
+-- computes on every build that has it: a modulus of one is zero whatever
+-- else is asked, and a negative exponent is a request for the inverse of
+-- the base raised to its magnitude, which is zero when no inverse exists.
+-- Read literally, the recursion below walked a negative exponent from -1 to
+-- -2 and back for as long as the stack held.
 exponentiation :: Integer -> Integer -> Integer -> Integer
 exponentiation b e m
-    | b == 1 = b
+    | m == 1 = 0
+    | e < 0 =
+        maybe 0 (\bInv -> exponentiation bInv (negate e) m) (inverse (b `mod` m) m)
+    | b == 1 = 1
     | e == 0 = 1
     | e == 1 = b `mod` m
     | even e =
diff --git a/Crypto/Number/Serialize/Internal.hs b/Crypto/Number/Serialize/Internal.hs
--- a/Crypto/Number/Serialize/Internal.hs
+++ b/Crypto/Number/Serialize/Internal.hs
@@ -53,7 +53,12 @@
     !padSz = ptrSz - sz
 
 fillPtr :: Ptr Word8 -> Int -> Integer -> IO ()
-fillPtr p sz m = gmpExportInteger m p `onGmpUnsupported` export (sz - 1) m
+fillPtr p sz m
+    -- zero is no bytes wide, and the callers above have already written the
+    -- room out as zeros.  Without this the loop below starts at offset -1,
+    -- never meets the 0 it stops at, and walks backwards out of the buffer.
+    | sz <= 0 = return ()
+    | otherwise = gmpExportInteger m p `onGmpUnsupported` export (sz - 1) m
   where
     export ofs i
         | ofs == 0 = pokeByteOff p ofs (fromIntegral i :: Word8)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,16 +3,14 @@
 crypton
 ==========
 
-Crypton is a fork from cryptonite with the original author's permission.
+`crypton` is a fork from `cryptonite` with the original author's permission.
 
-Crypton is a haskell repository of cryptographic primitives. Each crypto
-algorithm has specificities that are hard to wrap in common APIs and types,
-so instead of trying to provide a common ground for algorithms, this package
-provides a non-consistent low-level API.
 
-If you have no idea what you're doing, please do not use this directly.
-Instead, rely on higher level protocols or implementations.
+`crypton` is a low-level cryptography library. To achieve high
+performance, it utilizes C and assembly language to define FFI
+bindings, structuring them in a way that makes them easy to use.
 
+
 Side channels
 -------------
 
@@ -72,65 +70,55 @@
 Performance
 -----------
 
-The algorithms a TLS connection uses, measured against the previous release
-and against OpenSSL on the same machine.  Throughput is over 16 KiB messages;
-the public key operations are one operation each; every figure is the best of
-several runs, and crypton and OpenSSL are run alternately so that neither gets
-the quieter machine.
-
-The columns read 2.0.0 and are what 2.1.0 measures on every row but two.  The
-only C 2.1.0 changed is AES-GCM's and P-256's, and of those only P-256 is on
-a path these tables take: measured on the same EPYC 7763, ECDH P-256 goes
-164.3 to 159.5 microseconds and ECDSA P-256 verification 231.1 to 226.2, so
-those two rows are about 3% better than they read here.  ECDSA P-256 signing
-does not move, being the base-point path.  What 2.1.0 did to AES-GCM was add
-a one-call interface beside the one measured here -- key expanded once,
-additional data, payload and tag together -- which is worth 3.6 times at 100
-bytes and nothing at 16 KiB, so it does not show in a 16 KiB throughput
-figure at all.
+The algorithms a TLS connection uses, measured against the two releases
+behind this one and against OpenSSL on the same machine.  Throughput is over
+16 KiB messages; the public key operations are one operation each; every
+figure is the best of several runs, and crypton and OpenSSL are run
+alternately so that neither gets the quieter machine.
 
 Bulk encryption and hashing are measured through crypton's C layer, as
 `openssl speed` measures OpenSSL's.  The public key operations are measured
 through crypton's Haskell API, since that is where ECDSA and RSA live and it
 is what a program actually calls; the Haskell layer adds well under a
 microsecond, which the X25519 and ECDH P-256 rows confirm by agreeing with a
-C-level measurement to within a percent.  Both releases of crypton are built
-the same way -- `-optc-O3`, which is what both of them ask for -- and each
-column of a table comes from one run on the machine named above it.
+C-level measurement to within a percent.  All three releases of crypton are
+built the same way -- `-optc-O3`, which is what each asks for -- and by
+`cabal build`, since a copy of the sources compiled by hand does not measure
+what a program linking the library gets.  Each column of a table comes from
+one run on the machine named above it.
 
 ### x86-64
 
-An AMD EPYC 7763, which has AES-NI, PCLMULQDQ, AVX2, ADX and the SHA
-extensions, against OpenSSL 3.0.13.
+An AMD EPYC 7763, which has AES-NI, PCLMULQDQ, AVX2, ADX, VAES, VPCLMULQDQ
+and the SHA extensions, against OpenSSL 3.0.13.
 
 Throughput in MB/s, **higher is better**:
 
-| | crypton 1.1.5 | crypton 2.0.0 | OpenSSL | 2.0.0 / OpenSSL |
-| --- | ---: | ---: | ---: | ---: |
-| AES-128-GCM | 1331 | 4118 | 4264 | 0.97 |
-| AES-256-GCM | 1090 | 3810 | 3951 | 0.96 |
-| ChaCha20-Poly1305 | 398 | 2195 | 2191 | 1.00 |
-| SHA-1 | 738 | 1678 | 1672 | 1.00 |
-| SHA-256 | 286 | 1585 | 1570 | 1.01 |
-| SHA-512 | 448 | 769 | 746 | 1.03 |
-| SHA3-256 | 109 | 421 | 426 | 0.99 |
+| | crypton 1.1.5 | crypton 2.0.1 | crypton 2.1.2 | OpenSSL | 2.1.2 / OpenSSL |
+| --- | ---: | ---: | ---: | ---: | ---: |
+| AES-128-GCM | 1335 | 4243 | **6041** | 4287 | 1.41 |
+| AES-256-GCM | 1093 | 3932 | **5463** | 3954 | 1.38 |
+| ChaCha20-Poly1305 | 399 | 2196 | 2195 | 2192 | 1.00 |
+| SHA-1 | 729 | 1662 | 1680 | 1681 | 1.00 |
+| SHA-256 | 289 | 1586 | 1586 | 1570 | 1.01 |
+| SHA-512 | 449 | 770 | 770 | 748 | 1.03 |
+| SHA3-256 | 109 | 422 | 421 | 427 | 0.99 |
 
-Time per operation in microseconds, **lower is better** -- so the last column
-divides OpenSSL's time by crypton's, and is again better the larger it is:
+Time per operation in microseconds, **lower is better**:
 
-| | crypton 1.1.5 | crypton 2.0.0 | OpenSSL | OpenSSL / 2.0.0 |
-| --- | ---: | ---: | ---: | ---: |
-| X25519 | 43.57 | 43.52 | 36.58 | 0.84 |
-| ECDH P-256 | 163.8 | 163.7 | 52.36 | 0.32 |
-| ECDH P-384 | 2241 | 1101 | 857.1 | 0.78 |
-| Ed25519 sign | 28.52 | 28.25 | 43.49 | 1.54 |
-| Ed25519 verify | 46.06 | 46.16 | 119.3 | 2.59 |
-| ECDSA P-256 sign | 76.04 | 75.02 | 22.91 | 0.31 |
-| ECDSA P-256 verify | 229.2 | 228.5 | 67.98 | 0.30 |
-| ECDSA P-384 sign | 2271 | 387.6 | 904.3 | 2.33 |
-| ECDSA P-384 verify | 2667 | 1493 | 746.2 | 0.50 |
-| RSA-2048 sign/decrypt | 759.8 | 1311 | 660.1 | 0.50 |
-| RSA-2048 verify/encrypt | 31.62 | 28.59 | 18.63 | 0.65 |
+| | crypton 1.1.5 | crypton 2.0.1 | crypton 2.1.2 | OpenSSL | OpenSSL / 2.1.2 |
+| --- | ---: | ---: | ---: | ---: | ---: |
+| X25519 | 44.40 | 44.15 | **28.35** | 36.50 | 1.29 |
+| ECDH P-256 | 164.2 | 164.1 | **50.49** | 51.84 | 1.03 |
+| ECDH P-384 | 2220 | 1116 | **164.5** | 855.8 | 5.20 |
+| Ed25519 sign | 28.99 | 28.51 | 28.66 | 43.72 | 1.53 |
+| Ed25519 verify | 48.14 | 47.81 | 47.54 | 117.2 | 2.47 |
+| ECDSA P-256 sign | 81.43 | 80.79 | **18.62** | 22.45 | 1.21 |
+| ECDSA P-256 verify | 231.8 | 230.7 | **79.67** | 67.73 | 0.85 |
+| ECDSA P-384 sign | 2241 | 397.6 | **330.8** | 899.7 | 2.72 |
+| ECDSA P-384 verify | 2655 | 1519 | **500.5** | 734.5 | 1.47 |
+| RSA-2048 sign/decrypt | 758.3 | 1327 | **773.2** | 659.0 | 0.85 |
+| RSA-2048 verify/encrypt | 33.28 | 30.05 | 29.80 | 18.62 | 0.62 |
 
 ### AArch64
 
@@ -139,74 +127,90 @@
 
 Throughput in MB/s, **higher is better**:
 
-| | crypton 1.1.5 | crypton 2.0.0 | OpenSSL | 2.0.0 / OpenSSL |
-| --- | ---: | ---: | ---: | ---: |
-| AES-128-GCM | 126 | 8702 | 10719 | 0.81 |
-| AES-256-GCM | 98 | 7648 | 9154 | 0.84 |
-| ChaCha20-Poly1305 | 758 | 2323 | 2244 | 1.04 |
-| SHA-1 | 1199 | 3380 | 3346 | 1.01 |
-| SHA-256 | 467 | 3394 | 3352 | 1.01 |
-| SHA-512 | 723 | 1868 | 1851 | 1.01 |
-| SHA3-256 | 548 | 1091 | 1054 | 1.04 |
+| | crypton 1.1.5 | crypton 2.0.1 | crypton 2.1.2 | OpenSSL | 2.1.2 / OpenSSL |
+| --- | ---: | ---: | ---: | ---: | ---: |
+| AES-128-GCM | 127 | 8926 | 8731 | 10763 | 0.81 |
+| AES-256-GCM | 98 | 7601 | 7712 | 9155 | 0.84 |
+| ChaCha20-Poly1305 | 758 | 2247 | 2239 | 2248 | 1.00 |
+| SHA-1 | 1201 | 3307 | 3314 | 3296 | 1.01 |
+| SHA-256 | 472 | 3299 | 3245 | 3210 | 1.01 |
+| SHA-512 | 726 | 1766 | 1798 | 1794 | 1.00 |
+| SHA3-256 | 550 | 1076 | 1076 | 1054 | 1.02 |
 
-Time per operation in microseconds, **lower is better**; the last column again
-divides OpenSSL's time by crypton's:
+Time per operation in microseconds, **lower is better**:
 
-| | crypton 1.1.5 | crypton 2.0.0 | OpenSSL | OpenSSL / 2.0.0 |
-| --- | ---: | ---: | ---: | ---: |
-| X25519 | 18.44 | 18.41 | 18.41 | 1.00 |
-| ECDH P-256 | 69.46 | 56.24 | 24.68 | 0.44 |
-| ECDH P-384 | 3252 | 511.1 | 379.7 | 0.74 |
-| Ed25519 sign | 13.75 | 13.14 | 15.90 | 1.21 |
-| Ed25519 verify | 18.17 | 18.04 | 39.27 | 2.18 |
-| ECDSA P-256 sign | 32.56 | 27.91 | 11.05 | 0.40 |
-| ECDSA P-256 verify | 96.50 | 80.19 | 32.82 | 0.41 |
-| ECDSA P-384 sign | 3219 | 169.3 | 403.4 | 2.38 |
-| ECDSA P-384 verify | 3807 | 688.1 | 335.1 | 0.49 |
-| RSA-2048 sign/decrypt | 451.8 | 605.4 | 325.0 | 0.54 |
-| RSA-2048 verify/encrypt | 18.32 | 15.28 | 8.50 | 0.56 |
+| | crypton 1.1.5 | crypton 2.0.1 | crypton 2.1.2 | OpenSSL | OpenSSL / 2.1.2 |
+| --- | ---: | ---: | ---: | ---: | ---: |
+| X25519 | 18.25 | 18.27 | **12.05** | 18.27 | 1.52 |
+| ECDH P-256 | 69.07 | 56.23 | **20.70** | 24.62 | 1.19 |
+| ECDH P-384 | 3333 | 512.3 | **73.33** | 370.9 | 5.06 |
+| Ed25519 sign | 13.63 | 13.05 | 13.03 | 15.72 | 1.21 |
+| Ed25519 verify | 18.28 | 18.18 | 18.15 | 39.02 | 2.15 |
+| ECDSA P-256 sign | 32.35 | 27.80 | **6.98** | 11.02 | 1.58 |
+| ECDSA P-256 verify | 95.77 | 79.48 | **31.93** | 32.66 | 1.02 |
+| ECDSA P-384 sign | 3232 | 170.5 | **140.4** | 392.6 | 2.80 |
+| ECDSA P-384 verify | 3905 | 686.4 | **219.0** | 328.1 | 1.50 |
+| RSA-2048 sign/decrypt | 449.3 | 601.8 | 600.2 | 322.8 | 0.54 |
+| RSA-2048 verify/encrypt | 18.22 | 15.17 | 15.17 | 8.45 | 0.56 |
 
 ### What the numbers say
 
-1.1.5 had no AArch64 code of its own at all, which is why AES-GCM there is
-sixty-nine times what it was.  On x86-64 it had AES-NI and nothing else.  The
-curves over a prime field other than P-256 moved from Haskell `Integer`
-arithmetic into C, which is the nineteenfold change in ECDSA P-384 signing on
-the M4.  X25519 and Ed25519 are unchanged between the two releases, and the
-rows say so: where they differ by half a percent, that is the measurement and
-not the code.  P-256 is unchanged on x86-64 and a fifth faster on AArch64,
-which is the paragraph below.
+There are two changes in these tables, not one.  1.1.5 to 2.0.1 was a
+rewrite: the bulk algorithms moved into C, the curves other than P-256 moved
+out of Haskell `Integer` arithmetic, and everything that touches a secret was
+made to take the same time whatever the secret is.  1.1.5 had no AArch64 code
+of its own at all, which is why AES-GCM there is seventy times what it was,
+and on x86-64 it had AES-NI and nothing else.
 
-Where crypton is behind, it is behind for three separate reasons.
+2.0.1 to 2.1.2 is assembly, for the operations where C cannot reach.  The two
+columns beside each other say which change did what: ECDSA P-384 signing, for
+instance, got its nineteenfold from the first and a further fifth from the
+second, while X25519 waited for the second entirely.
 
-*P-256.*  crypton's field arithmetic is C where OpenSSL's is hand-written
-assembly, and that is what is left of the difference: the two differ by about
-the same factor on every P-256 row, and nothing above the field -- a wider
-window, a different addition formula, another field representation -- recovers
-a useful part of it.
+Most of that assembly is not crypton's.  The prime curves, the inverse modulo
+a group order, X25519, and RSA's Montgomery multiplication on x86-64 go
+through [s2n-bignum](https://github.com/awslabs/s2n-bignum), vendored in
+`cbits/s2n`.  Every routine in it carries a machine-checked proof in
+HOL-Light that it computes what it says, and is written in a constant-time
+style.  It is `Apache-2.0 OR ISC OR MIT-0`, and crypton takes it under ISC.
 
-The AArch64 rows are better than the x86-64 ones because of where a field
-multiplication's latency goes.  It ends in a carry chain the width of the
-number, and the curve arithmetic has independent products that could cover
-that chain -- but only if the compiler inlines the reduction instead of
-calling it, since a call is a fence.  Asking it to costs code and pays where
-there are registers enough to hold two chains at once: a quarter on AArch64,
-where there are thirty-one, and nothing on x86-64, where there are fifteen and
-the same request makes it slower.  So x86-64 is left to the compiler's own
-judgement and stays at 0.3.
+That licence is why any of this was possible.  The obvious assembly to reach
+for is OpenSSL's and BoringSSL's `ecp_nistz256`, and it cannot be used here:
+it is Apache-2.0 only, and Intel and CloudFlare hold copyright in it besides
+OpenSSL, so nobody is in a position to relicense it.
 
-*RSA signing.*  2.0.0 is slower than 1.1.5 here on purpose.  Its modular
-exponentiation no longer indexes a table with the bits of the exponent, and
-hiding the exponent is what the difference buys.  What is left of the gap
-against OpenSSL is the Montgomery multiplication, which is assembly there and
-C here.
+Where crypton is still behind, it is behind for two reasons.
 
-*The AVX-512 instructions.*  Neither machine above has them.  On one that does
--- an EPYC 9V74, measured the same way -- OpenSSL uses them for AES-GCM and
-ChaCha20 and reaches 12003 and 3789 MB/s, against 4745 and 2372 for crypton,
-whose vendored assembly is generated without them.  Those ratios are 0.40 and
-0.63 rather than 0.97 and 1.00.  Nothing else in either table moves by more
-than a few percent between the two processors.
+*RSA.*  2.0.0 made signing slower than 1.1.5 on purpose: its modular
+exponentiation stopped indexing a table with the bits of the exponent, and
+hiding the exponent is what the difference bought.  On x86-64 that cost is
+now repaid -- s2n-bignum's Montgomery multiplication is twice the C's,
+because the C cannot form the two carry chains `ADCX` and `ADOX` give, and
+2.1.2 signs in about what 1.1.5 took while keeping what 2.0.0 gained.  On
+AArch64 the C measures faster than that assembly, so none is used and the gap
+stays.  Verification does not move either way: its exponent is 65537,
+seventeen bits, and there is no exponentiation to speak of.
+
+*The wide AES instructions.*  `VAES` and `VPCLMULQDQ` do two blocks where
+`AES-NI` and `PCLMULQDQ` do one, and four in their 512-bit form.  crypton uses
+the 256-bit form where the processor has it, which is Zen 3 and Ice Lake
+onwards, and the 512-bit form where that is worth having, which is Ice Lake and
+Zen 5 onwards.  There was nothing to borrow: the wide AES-GCM in OpenSSL,
+BoringSSL and AWS-LC is Apache-2.0 and s2n-bignum has no GCM, so both files are
+crypton's own.
+
+The 512-bit path arrived after 2.1.2, and neither machine in the tables above
+has AVX-512, so it is in neither column.  On the runners that do, measured
+over 16 KiB in MB/s: an EPYC 9V45 (Zen 5) goes from
+9616 to 14268 with it, a Xeon 6973P-C from 8095 to 9848, a Xeon 8573C from 6983
+to 8447.  OpenSSL on those machines is ahead still -- 25760 on the first of
+them -- because it interleaves the GHASH with the AES where crypton does them
+in turn.  Zen 4 keeps the 256-bit path: its 512-bit instructions are two passes
+through a 256-bit datapath, so the wider encoding buys nothing there and costs
+a little.
+
+AArch64 has no counterpart to any of these, which is where the 0.8 on its
+AES-GCM rows comes from.
 
 One row wants a word of its own: crypton's `Ed25519.sign` derives the public
 key from the secret key every time it signs, so that a caller who passes a
diff --git a/cbits/LICENSE.go b/cbits/LICENSE.go
new file mode 100644
--- /dev/null
+++ b/cbits/LICENSE.go
@@ -0,0 +1,38 @@
+The arrangement of the AArch64 multiply-accumulate loop in
+cbits/crypton_bignum.h -- four limbs to an iteration, the low halves of the
+products and the high halves accumulated in two chains -- follows
+addMulVVWx in Go's crypto/internal/fips140/bigmod/nat_arm64.s, written out
+in the assembler that file's compiler speaks.  Go is at
+https://github.com/golang/go and carries the licence below.  That file's
+own header reads "Copyright 2013 The Go Authors. All rights reserved.  Use
+of this source code is governed by a BSD-style license that can be found in
+the LICENSE file", and the LICENSE file it means is this one.
+
+
+Copyright 2009 The Go Authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google LLC nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cbits/aes/armv8_impl.c b/cbits/aes/armv8_impl.c
--- a/cbits/aes/armv8_impl.c
+++ b/cbits/aes/armv8_impl.c
@@ -262,6 +262,43 @@
  *
  * GCM's counter is the low 32 bits only and wraps there, so unlike CTR
  * there is no carry to chase: the top twelve bytes never move.
+ *
+ * What this loop is short of is not overlap but instructions.  A group of
+ * eight blocks compiles to 383 of them on an Apple M4, and only 152 are the
+ * cipher -- eighty AESE and seventy-two AESMC.  The rest is the GHASH and
+ * the counters.  Measured against OpenSSL on the same machine, 16 KiB
+ * messages under AES-128:
+ *
+ *     crypton, this loop with the GHASH taken out     19883 MB/s
+ *     OpenSSL, AES-128-CTR                            17176
+ *     OpenSSL, AES-128-GCM                             9869
+ *     crypton, AES-128-GCM                             8641
+ *
+ * The cipher here is ahead of OpenSSL's; all of the 0.87 is the GHASH.
+ * Four ways of closing it were tried and every one measured worse, so they
+ * are written down here rather than tried again.  Each was checked to give
+ * the same ciphertext and tag as this code for three key sizes and
+ * thirty-five lengths, encrypt and decrypt, before being timed:
+ *
+ *     the GHASH held back a group and spread through the next    -1.3%
+ *       group's AES rounds, so that the two do not queue         to -3.6%
+ *     Karatsuba: three multiplications for the two halves        -1.6%
+ *       instead of four
+ *     the same with every product on a lane the instruction       0.0%
+ *       reaches, which does remove sixteen fmov a group
+ *     the same again with the H powers' halves added together    -3%
+ *       already, in the spare half of htable
+ *
+ * The first fails because there was nothing to gain: a group's AES depends
+ * on nothing in the group before it, so a wide out-of-order core already
+ * runs the two together, and holding a group back only adds copies.  The
+ * rest fail for one reason -- none of them makes the loop shorter.
+ * Karatsuba buys a PMULL for two EOR and an EXT, and the folded table turns
+ * sixteen `dup` into sixteen `ld1r` and sixteen more address adds.  A count
+ * that does come down wants the data laid out differently, which is what
+ * OpenSSL's aes-gcm-armv8_64.pl is; it is Apache-2.0 and in OpenSSL's tree
+ * only, and CRYPTOGAMS, which cbits/asm vendors from, publishes AES and
+ * GHASH separately and nothing that stitches them.
  */
 #define GCM_CTR(i)   s[i] = vreinterpretq_u8_u32(vsetq_lane_u32(cpu_to_be32(c + 1 + (i)), base, 3));
 #define GCM_ENC(i)   { const uint8x16_t m_ = vld1q_u8(input + 16 * (i)); \
diff --git a/cbits/aes/block128.h b/cbits/aes/block128.h
--- a/cbits/aes/block128.h
+++ b/cbits/aes/block128.h
@@ -34,7 +34,21 @@
 #include <crypton_bitfn.h>
 #include <crypton_align.h>
 
-typedef union {
+/* Packed, so that the union asks nothing of the address it is at.
+ *
+ * Several callers here make one of these out of a pointer of their own -- a
+ * ciphertext, a tag, a nonce -- and without this that cast produces a pointer
+ * the standard says may not exist, and reading q[] out of it is a member
+ * access at an address the type is not aligned for.  crypton_align.h used to
+ * answer that with need_alignment, which is zero on i386 and x86-64: the two
+ * places the access is architecturally fine and the standard still says
+ * nothing about it.  UndefinedBehaviorSanitizer reported it.
+ *
+ * With the alignment declared to be one, the compiler is the one that knows
+ * what the target can do: on i386, x86-64 and AArch64 it emits the same load
+ * and store it emitted before, and where a target cannot read a word off an
+ * odd address it emits what that target needs. */
+typedef union __attribute__((packed)) {
        uint64_t q[2];
        uint32_t d[4];
        uint16_t w[8];
diff --git a/cbits/aes/gcm_fused_x86.c b/cbits/aes/gcm_fused_x86.c
--- a/cbits/aes/gcm_fused_x86.c
+++ b/cbits/aes/gcm_fused_x86.c
@@ -55,19 +55,30 @@
     return _mm_xor_si128(a, _mm_unpackhi_epi64(a, a));
 }
 
-/* GCM numbers the bits of a field element the other way round from the way
- * the carry-less multiply does.  Pre-shifting H is what saves the correction
- * after every multiply; the bit that falls off the top is the one the
- * polynomial reduces. */
+/* H multiplied by x in the field, which is what puts H and its powers one
+ * bit up: GCM numbers the bits of a field element the other way round from
+ * the way the carry-less multiply does, and pre-shifting is what saves the
+ * correction after every multiply.
+ *
+ * Written from the definition.  The field is GF(2)[x] modulo x^128 + x^127 +
+ * x^126 + x^121 + 1, so multiplying by x is a shift of one place, and the
+ * term that leaves the top comes back as the other four. */
 TGT static __m128i twist(__m128i h)
 {
+    /* x^127 + x^126 + x^121 + 1, the terms x^128 is congruent to */
     const __m128i poly = _mm_set_epi64x(0xc200000000000000ULL, 1);
-    __m128i carried = _mm_slli_si128(_mm_srli_epi64(h, 63), 8);
-    __m128i top = _mm_shuffle_epi32(h, 0xff);
-    __m128i reduce = _mm_cmpgt_epi32(_mm_setzero_si128(), top);
+    /* the top bit of each half */
+    __m128i tops = _mm_srli_epi64(h, 63);
+    /* doubling a polynomial is a shift by one: each half doubles, and the
+     * low half's top bit becomes the high half's bottom bit */
+    __m128i doubled = _mm_or_si128(_mm_add_epi64(h, h),
+                                   _mm_slli_si128(tops, 8));
+    /* bit 127 is the one that leaves the field; spread it to a mask by
+     * subtracting it from zero, and it brings the four terms back */
+    __m128i mask = _mm_sub_epi64(_mm_setzero_si128(),
+                                 _mm_unpackhi_epi64(tops, tops));
 
-    h = _mm_or_si128(_mm_slli_epi64(h, 1), carried);
-    return _mm_xor_si128(h, _mm_and_si128(reduce, poly));
+    return _mm_xor_si128(doubled, _mm_and_si128(mask, poly));
 }
 
 /* one reduction of a 256-bit product back into the field */
diff --git a/cbits/aes/gcm_vaes512_x86.c b/cbits/aes/gcm_vaes512_x86.c
new file mode 100644
--- /dev/null
+++ b/cbits/aes/gcm_vaes512_x86.c
@@ -0,0 +1,364 @@
+/*
+ * AES-GCM through VAES and VPCLMULQDQ in their 512-bit form, which takes
+ * four blocks where the 256-bit form in cbits/aes/gcm_vaes_x86.c takes two
+ * and the 128-bit one takes one.  The instruction rate is the same, so the
+ * work per group halves again.
+ *
+ * This is that file widened and nothing else: the same group of sixteen
+ * blocks, the same descending powers of H sharing one reduction, the same
+ * round keys read from memory rather than held in registers.  Four blocks to
+ * a register means the group fills four of them rather than eight, which is
+ * what leaves room for the group's own ciphertext to be kept for the GHASH
+ * when encrypting.
+ *
+ * Nothing here is borrowed.  OpenSSL's and BoringSSL's AVX-512 AES-GCM is
+ * Apache-2.0 and s2n-bignum has no GCM at all.
+ *
+ * The reduction at the end is a copy of the one in gcm_vaes_x86.c rather
+ * than a call to it: the two files are compiled for different instruction
+ * sets, and a function compiled for one cannot be inlined into the other.
+ */
+#include "aes/gcm_vaes512_x86.h"
+
+#ifdef WITH_GCM_VAES512
+
+#include <string.h>
+#include <immintrin.h>
+
+#include <aes/gf.h>
+#include <aes/block128.h>
+
+#if defined(__clang__) || defined(__GNUC__)
+#define V512_TARGET \
+	__attribute__((target("avx512f,avx512bw,avx512vl,aes,pclmul,vaes,vpclmulqdq")))
+#else
+#define V512_TARGET
+#endif
+
+/*
+ * Thirty-two blocks to a group, four to a register, so eight registers are
+ * in flight.  The number of registers is what matters as much as the blocks
+ * per instruction: AES-NI has a latency of four cycles against a throughput
+ * of one, so it takes eight independent chains to keep two ports busy.  Four
+ * registers of four blocks was written first and measured *slower* than the
+ * 256-bit path -- the blocks per instruction had doubled and the chains had
+ * halved.
+ *
+ * The table holds sixteen powers of H, so the GHASH of a group is two passes
+ * of sixteen blocks, the second picking up the tag the first leaves.
+ */
+#define V512WIDE 8
+#define V512HALF 4
+#define V512BYTES 512
+
+/*
+ * The 128-bit multiply of cbits/aes/x86ni.c, done in all four lanes at once.
+ * Every shuffle and shift here works inside its own 128-bit lane, so the
+ * four products never mix: what comes out is four independent carry-less
+ * products, accumulated by the caller and reduced together at the end.
+ */
+V512_TARGET
+static inline void clmul512(__m512i a, __m512i b, __m512i *lo, __m512i *hi)
+{
+	const __m512i bswap = _mm512_set4_epi32(
+		0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f);
+	__m512i t3, t4, t5, t6;
+
+	a = _mm512_shuffle_epi8(a, bswap);
+
+	/* Karatsuba, as in the 128-bit one: three multiplies, not four */
+	t3 = _mm512_clmulepi64_epi128(a, b, 0x00);
+	t6 = _mm512_clmulepi64_epi128(a, b, 0x11);
+	t4 = _mm512_clmulepi64_epi128(
+		_mm512_xor_si512(a, _mm512_shuffle_epi32(a, _MM_PERM_BADC)),
+		_mm512_xor_si512(b, _mm512_shuffle_epi32(b, _MM_PERM_BADC)),
+		0x00);
+	t4 = _mm512_xor_si512(t4, _mm512_xor_si512(t3, t6));
+
+	t5 = _mm512_bslli_epi128(t4, 8);
+	t4 = _mm512_bsrli_epi128(t4, 8);
+
+	*lo = _mm512_xor_si512(t3, t5);
+	*hi = _mm512_xor_si512(t6, t4);
+}
+
+/*
+ * The reduction of cbits/aes/x86ni.c.  By the time it runs the four lanes
+ * have been folded into one, so there is one 256-bit product to reduce.
+ */
+V512_TARGET
+static inline __m128i gfred512(__m128i t3, __m128i t6)
+{
+	const __m128i bswap = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
+	__m128i t2, t4, t5, t7, t8, t9;
+
+	t7 = _mm_srli_epi32(t3, 31);
+	t8 = _mm_srli_epi32(t6, 31);
+	t3 = _mm_slli_epi32(t3, 1);
+	t6 = _mm_slli_epi32(t6, 1);
+
+	t9 = _mm_srli_si128(t7, 12);
+	t8 = _mm_slli_si128(t8, 4);
+	t7 = _mm_slli_si128(t7, 4);
+	t3 = _mm_or_si128(t3, t7);
+	t6 = _mm_or_si128(t6, t8);
+	t6 = _mm_or_si128(t6, t9);
+
+	t7 = _mm_slli_epi32(t3, 31);
+	t8 = _mm_slli_epi32(t3, 30);
+	t9 = _mm_slli_epi32(t3, 25);
+
+	t7 = _mm_xor_si128(t7, t8);
+	t7 = _mm_xor_si128(t7, t9);
+	t8 = _mm_srli_si128(t7, 4);
+	t7 = _mm_slli_si128(t7, 12);
+	t3 = _mm_xor_si128(t3, t7);
+
+	t2 = _mm_srli_epi32(t3, 1);
+	t4 = _mm_srli_epi32(t3, 2);
+	t5 = _mm_srli_epi32(t3, 7);
+	t2 = _mm_xor_si128(t2, t4);
+	t2 = _mm_xor_si128(t2, t5);
+	t2 = _mm_xor_si128(t2, t8);
+	t3 = _mm_xor_si128(t3, t2);
+	t6 = _mm_xor_si128(t6, t3);
+
+	return _mm_shuffle_epi8(t6, bswap);
+}
+
+/* the four 128-bit lanes of a register added together */
+V512_TARGET
+static inline __m128i fold512(__m512i v)
+{
+	__m256i h = _mm256_xor_si256(_mm512_castsi512_si256(v),
+	                             _mm512_extracti64x4_epi64(v, 1));
+
+	return _mm_xor_si128(_mm256_castsi256_si128(h),
+	                     _mm256_extracti128_si256(h, 1));
+}
+
+/*
+ * Sixteen blocks against H^16 .. H^1, one reduction.  v[j] holds blocks 4j
+ * to 4j+3 in its four lanes, so the powers for it are H^(16-4j) down to
+ * H^(13-4j) -- the table's own order the other way round, hence the four
+ * 128-bit loads rather than one 512-bit one.
+ */
+V512_TARGET
+static inline __m128i ghash16(__m128i tag, const table_4bit htable,
+                              const __m512i *v, int fromwire)
+{
+	__m512i lo = _mm512_setzero_si512(), hi = _mm512_setzero_si512();
+	__m512i l, h, b;
+	int j;
+
+	for (j = 0; j < V512HALF; j++) {
+		const __m128i p0 =
+			_mm_loadu_si128((const __m128i *) &htable[15 - 4 * j]);
+		const __m128i p1 =
+			_mm_loadu_si128((const __m128i *) &htable[14 - 4 * j]);
+		const __m128i p2 =
+			_mm_loadu_si128((const __m128i *) &htable[13 - 4 * j]);
+		const __m128i p3 =
+			_mm_loadu_si128((const __m128i *) &htable[12 - 4 * j]);
+		__m512i hp = _mm512_castsi128_si512(p0);
+
+		hp = _mm512_inserti32x4(hp, p1, 1);
+		hp = _mm512_inserti32x4(hp, p2, 2);
+		hp = _mm512_inserti32x4(hp, p3, 3);
+
+		b = fromwire ? _mm512_loadu_si512(v + j) : v[j];
+		if (j == 0) /* the running tag joins the first block */
+			b = _mm512_xor_si512(
+				b, _mm512_inserti32x4(
+					_mm512_setzero_si512(), tag, 0));
+		clmul512(b, hp, &l, &h);
+		lo = _mm512_xor_si512(lo, l);
+		hi = _mm512_xor_si512(hi, h);
+	}
+
+	/* the four lanes are independent products of the same sum: fold them */
+	return gfred512(fold512(lo), fold512(hi));
+}
+
+#define KK512(r) _mm512_broadcast_i32x4(_mm_loadu_si128(k_ + (r)))
+
+#define AESENC32(K)                                                         \
+	do {                                                                \
+		const __m512i rk = (K);                                     \
+		v[0] = _mm512_aesenc_epi128(v[0], rk);                      \
+		v[1] = _mm512_aesenc_epi128(v[1], rk);                      \
+		v[2] = _mm512_aesenc_epi128(v[2], rk);                      \
+		v[3] = _mm512_aesenc_epi128(v[3], rk);                      \
+		v[4] = _mm512_aesenc_epi128(v[4], rk);                      \
+		v[5] = _mm512_aesenc_epi128(v[5], rk);                      \
+		v[6] = _mm512_aesenc_epi128(v[6], rk);                      \
+		v[7] = _mm512_aesenc_epi128(v[7], rk);                      \
+	} while (0)
+
+#define AESLAST32(K)                                                        \
+	do {                                                                \
+		const __m512i rk = (K);                                     \
+		v[0] = _mm512_aesenclast_epi128(v[0], rk);                  \
+		v[1] = _mm512_aesenclast_epi128(v[1], rk);                  \
+		v[2] = _mm512_aesenclast_epi128(v[2], rk);                  \
+		v[3] = _mm512_aesenclast_epi128(v[3], rk);                  \
+		v[4] = _mm512_aesenclast_epi128(v[4], rk);                  \
+		v[5] = _mm512_aesenclast_epi128(v[5], rk);                  \
+		v[6] = _mm512_aesenclast_epi128(v[6], rk);                  \
+		v[7] = _mm512_aesenclast_epi128(v[7], rk);                  \
+	} while (0)
+
+#define XOR32(K)                                                            \
+	do {                                                                \
+		const __m512i rk = (K);                                     \
+		v[0] = _mm512_xor_si512(v[0], rk);                          \
+		v[1] = _mm512_xor_si512(v[1], rk);                          \
+		v[2] = _mm512_xor_si512(v[2], rk);                          \
+		v[3] = _mm512_xor_si512(v[3], rk);                          \
+		v[4] = _mm512_xor_si512(v[4], rk);                          \
+		v[5] = _mm512_xor_si512(v[5], rk);                          \
+		v[6] = _mm512_xor_si512(v[6], rk);                          \
+		v[7] = _mm512_xor_si512(v[7], rk);                          \
+	} while (0)
+
+/*
+ * The rounds are written out rather than looped for the reason the 128-bit
+ * loop gives: the count is a value in the key, and a loop over it leaves the
+ * round key reached through an index the compiler cannot fold.
+ */
+V512_TARGET
+static inline __attribute__((always_inline)) void
+rounds32(__m512i *v, const uint8_t *k, const int nbr)
+{
+	const __m128i *k_ = (const __m128i *) k;
+
+	XOR32(KK512(0));
+	AESENC32(KK512(1)); AESENC32(KK512(2)); AESENC32(KK512(3));
+	AESENC32(KK512(4)); AESENC32(KK512(5)); AESENC32(KK512(6));
+	AESENC32(KK512(7)); AESENC32(KK512(8)); AESENC32(KK512(9));
+	if (nbr > 10) {
+		AESENC32(KK512(10)); AESENC32(KK512(11));
+		if (nbr > 12) {
+			AESENC32(KK512(12)); AESENC32(KK512(13));
+		}
+	}
+	AESLAST32(_mm512_broadcast_i32x4(_mm_loadu_si128(k_ + nbr)));
+}
+
+/* sixteen consecutive counters, four to a register.  GCM counts in the low
+ * thirty-two bits and wraps there, which is what _mm_add_epi32 does. */
+V512_TARGET
+static inline __m128i counters32(__m512i *v, __m128i iv, __m128i one,
+                                 __m128i bswap)
+{
+	int j;
+
+	for (j = 0; j < V512WIDE; j++) {
+		__m128i c0, c1, c2, c3;
+		__m512i c;
+
+		iv = _mm_add_epi32(iv, one);
+		c0 = _mm_shuffle_epi8(iv, bswap);
+		iv = _mm_add_epi32(iv, one);
+		c1 = _mm_shuffle_epi8(iv, bswap);
+		iv = _mm_add_epi32(iv, one);
+		c2 = _mm_shuffle_epi8(iv, bswap);
+		iv = _mm_add_epi32(iv, one);
+		c3 = _mm_shuffle_epi8(iv, bswap);
+
+		c = _mm512_castsi128_si512(c0);
+		c = _mm512_inserti32x4(c, c1, 1);
+		c = _mm512_inserti32x4(c, c2, 2);
+		c = _mm512_inserti32x4(c, c3, 3);
+		v[j] = c;
+	}
+	return iv;
+}
+
+/*
+ * Inlined into three callers with the round count a constant in each, which
+ * folds away the tests inside the group loop -- the same reason the 256-bit
+ * file gives, where without it AES-256 lost what AES-128 gained.
+ */
+V512_TARGET
+static inline __attribute__((always_inline)) uint32_t
+bulk_n(uint8_t *output, aes_gcm *gcm, const aes_key *key,
+       const uint8_t *input, uint32_t length, int decrypt, const int nbr)
+{
+	const __m128i bswap = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8);
+	const __m128i one = _mm_set_epi32(0, 1, 0, 0);
+	__m512i v[V512WIDE];
+	__m128i iv, tag;
+	uint32_t groups = length / V512BYTES;
+	uint32_t done = 0;
+	uint32_t g;
+	int j;
+
+	if (groups == 0)
+		return 0;
+
+	iv = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *) &gcm->civ), bswap);
+	tag = _mm_loadu_si128((const __m128i *) &gcm->tag);
+
+	for (g = 0; g < groups; g++, input += V512BYTES, output += V512BYTES,
+	     done += V512BYTES) {
+		iv = counters32(v, iv, one, bswap);
+		rounds32(v, key->data, nbr);
+
+		for (j = 0; j < V512WIDE; j++) {
+			const __m512i in =
+				_mm512_loadu_si512((const __m512i *) (input + 64 * j));
+
+			v[j] = _mm512_xor_si512(v[j], in);
+			_mm512_storeu_si512((__m512i *) (output + 64 * j), v[j]);
+		}
+		/* sixteen blocks to a pass, since that is how many powers of
+		 * H the table holds; the second picks up the tag the first
+		 * leaves */
+		tag = ghash16(tag, gcm->htable,
+		              decrypt ? (const __m512i *) input : v,
+		              decrypt);
+		tag = ghash16(tag, gcm->htable,
+		              decrypt ? (const __m512i *) (input + 256)
+		                      : v + V512HALF,
+		              decrypt);
+	}
+
+	_mm_storeu_si128((__m128i *) &gcm->civ, _mm_shuffle_epi8(iv, bswap));
+	_mm_storeu_si128((__m128i *) &gcm->tag, tag);
+	return done;
+}
+
+V512_TARGET
+static uint32_t bulk(uint8_t *output, aes_gcm *gcm, const aes_key *key,
+                     const uint8_t *input, uint32_t length, int decrypt)
+{
+	switch (key->nbr) {
+	case 10:
+		return bulk_n(output, gcm, key, input, length, decrypt, 10);
+	case 12:
+		return bulk_n(output, gcm, key, input, length, decrypt, 12);
+	case 14:
+		return bulk_n(output, gcm, key, input, length, decrypt, 14);
+	default:
+		return 0; /* not a key length AES has */
+	}
+}
+
+uint32_t crypton_gcm_vaes512_bulk_encrypt(uint8_t *output, aes_gcm *gcm,
+                                          const aes_key *key,
+                                          const uint8_t *input,
+                                          uint32_t length)
+{
+	return bulk(output, gcm, key, input, length, 0);
+}
+
+uint32_t crypton_gcm_vaes512_bulk_decrypt(uint8_t *output, aes_gcm *gcm,
+                                          const aes_key *key,
+                                          const uint8_t *input,
+                                          uint32_t length)
+{
+	return bulk(output, gcm, key, input, length, 1);
+}
+
+#endif
diff --git a/cbits/aes/gcm_vaes512_x86.h b/cbits/aes/gcm_vaes512_x86.h
new file mode 100644
--- /dev/null
+++ b/cbits/aes/gcm_vaes512_x86.h
@@ -0,0 +1,37 @@
+/*
+ * AES-GCM in the 512-bit form of the AES and carry-less multiply
+ * instructions, which do four blocks where the 128-bit ones do one and the
+ * 256-bit ones in cbits/aes/gcm_vaes_x86.c do two.
+ */
+#ifndef CRYPTON_GCM_VAES512_X86_H
+#define CRYPTON_GCM_VAES512_X86_H
+
+#include <crypton_cpu.h>
+
+#if defined(ARCH_X86) && defined(__x86_64__) && defined(WITH_AESNI) \
+    && defined(WITH_PCLMUL)
+#define WITH_GCM_VAES512
+#endif
+
+#ifdef WITH_GCM_VAES512
+
+#include <stdint.h>
+#include <crypton_aes.h>
+
+/* The same contract as the 256-bit pair: whole groups off the front, the
+ * counter left in gcm->civ and the running tag in gcm->tag, and the number
+ * of bytes taken returned, a multiple of 512 and possibly zero. */
+uint32_t crypton_gcm_vaes512_bulk_encrypt(uint8_t *output, aes_gcm *gcm,
+                                          const aes_key *key,
+                                          const uint8_t *input,
+                                          uint32_t length);
+uint32_t crypton_gcm_vaes512_bulk_decrypt(uint8_t *output, aes_gcm *gcm,
+                                          const aes_key *key,
+                                          const uint8_t *input,
+                                          uint32_t length);
+
+/* Thirty-two blocks is the least it will start on. */
+#define GCM_VAES512_MIN_BLOCKS 32
+
+#endif
+#endif
diff --git a/cbits/aes/gcm_x86_asm.c b/cbits/aes/gcm_x86_asm.c
--- a/cbits/aes/gcm_x86_asm.c
+++ b/cbits/aes/gcm_x86_asm.c
@@ -92,19 +92,29 @@
  * H, and every power of it, is kept shifted up by one bit: GCM numbers the
  * bits of a field element the other way round from the way the carry-less
  * multiply does, and pre-shifting the operand is what saves the correction
- * after each multiply.  The bit that falls off the top is the one that the
- * polynomial reduces.
+ * after each multiply.
+ *
+ * Written from the definition.  The field is GF(2)[x] modulo x^128 + x^127 +
+ * x^126 + x^121 + 1, so multiplying by x is a shift of one place, and the
+ * term that leaves the top comes back as the other four.
  */
 TARGET_PCLMUL
 static __m128i twist(__m128i h)
 {
+	/* x^127 + x^126 + x^121 + 1, the terms x^128 is congruent to */
 	const __m128i poly = _mm_set_epi64x(0xc200000000000000ULL, 1);
-	__m128i carried = _mm_slli_si128(_mm_srli_epi64(h, 63), 8);
-	__m128i top = _mm_shuffle_epi32(h, 0xff);
-	__m128i reduce = _mm_cmpgt_epi32(_mm_setzero_si128(), top);
+	/* the top bit of each half */
+	__m128i tops = _mm_srli_epi64(h, 63);
+	/* doubling a polynomial is a shift by one: each half doubles, and the
+	 * low half's top bit becomes the high half's bottom bit */
+	__m128i doubled = _mm_or_si128(_mm_add_epi64(h, h),
+	                               _mm_slli_si128(tops, 8));
+	/* bit 127 is the one that leaves the field; spread it to a mask by
+	 * subtracting it from zero, and it brings the four terms back */
+	__m128i mask = _mm_sub_epi64(_mm_setzero_si128(),
+	                             _mm_unpackhi_epi64(tops, tops));
 
-	h = _mm_or_si128(_mm_slli_epi64(h, 1), carried);
-	return _mm_xor_si128(h, _mm_and_si128(reduce, poly));
+	return _mm_xor_si128(doubled, _mm_and_si128(mask, poly));
 }
 
 /* the two halves of a value added together, which is the term Karatsuba
diff --git a/cbits/aes/x86ni.c b/cbits/aes/x86ni.c
--- a/cbits/aes/x86ni.c
+++ b/cbits/aes/x86ni.c
@@ -38,6 +38,7 @@
 #include <aes/gf.h>
 #include <aes/x86ni.h>
 #include <aes/gcm_vaes_x86.h>
+#include <aes/gcm_vaes512_x86.h>
 #include <aes/block128.h>
 #include <aes/gcm_x86_asm.h>
 
diff --git a/cbits/aes/x86ni_impl.c b/cbits/aes/x86ni_impl.c
--- a/cbits/aes/x86ni_impl.c
+++ b/cbits/aes/x86ni_impl.c
@@ -335,12 +335,28 @@
 
 	gcm->length_input += length;
 
+#ifdef WITH_GCM_VAES512
+	/*
+	 * The widest form the processor has, first: four blocks to an
+	 * instruction where the 256-bit one below takes two and the assembly
+	 * after that takes one.  Same contract throughout -- whole groups off
+	 * the front, the counter and the tag left behind.
+	 */
+	if (nb_blocks >= GCM_VAES512_MIN_BLOCKS
+	    && (crypton_x86_simd_features() & CRYPTON_X86_VAES512)) {
+		uint32_t done = crypton_gcm_vaes512_bulk_encrypt(
+			output, gcm, key, input, nb_blocks * 16);
+
+		output += done;
+		input += done;
+		nb_blocks -= done / 16;
+	}
+#endif
 #ifdef WITH_GCM_VAES
 	/*
-	 * The 256-bit instructions first where the processor has them: they
-	 * take two blocks where the ones below take one, and the assembly
-	 * that follows is 128-bit throughout.  Same contract -- whole groups
-	 * off the front, the counter and the tag left behind.
+	 * The 256-bit instructions next: they take two blocks where the ones
+	 * below take one, and the assembly that follows is 128-bit
+	 * throughout.
 	 */
 	if (nb_blocks >= GCM_VAES_MIN_BLOCKS
 	    && (crypton_x86_simd_features() & CRYPTON_X86_VAES)) {
@@ -501,6 +517,18 @@
 
 	gcm->length_input += length;
 
+#ifdef WITH_GCM_VAES512
+	/* as in encryption; the tag is taken over the input here */
+	if (nb_blocks >= GCM_VAES512_MIN_BLOCKS
+	    && (crypton_x86_simd_features() & CRYPTON_X86_VAES512)) {
+		uint32_t done = crypton_gcm_vaes512_bulk_decrypt(
+			output, gcm, key, input, nb_blocks * 16);
+
+		output += done;
+		input += done;
+		nb_blocks -= done / 16;
+	}
+#endif
 #ifdef WITH_GCM_VAES
 	/* as in encryption; the tag is taken over the input here */
 	if (nb_blocks >= GCM_VAES_MIN_BLOCKS
diff --git a/cbits/crypton_aes.c b/cbits/crypton_aes.c
--- a/cbits/crypton_aes.c
+++ b/cbits/crypton_aes.c
@@ -425,7 +425,22 @@
 }
 #endif
 
-uint8_t *crypton_aes_cpu_init(void)
+/* Which implementation each entry of the branch table names is decided once,
+ * before anything else runs.
+ *
+ * It used to be decided again on every crypton_aes_initkey, which meant two
+ * threads taking a key at the same time were writing the whole table at the
+ * same time -- a data race for as long as the program used AES, not just at
+ * the start.  ThreadSanitizer reports forty-two of them for eight threads
+ * doing nothing but taking keys.  The values written are the same ones every
+ * time and the table starts out holding valid generic implementations, so
+ * nothing has ever come of it; it is a race the standard gives no meaning to
+ * all the same.
+ *
+ * A constructor runs while there is one thread, which is the cheapest way to
+ * have no race at all: no flag to test, no lock to take, and one less thing
+ * for crypton_aes_initkey to do per key. */
+static void crypton_aes_cpu_setup(void)
 {
 #if defined(ARCH_X86) && defined(WITH_AESNI)
 	crypton_aesni_initialize_hw(initialize_table_ni);
@@ -433,6 +448,16 @@
 #ifdef WITH_ARMV8_CRYPTO
 	initialize_table_armv8();
 #endif
+}
+
+__attribute__((constructor))
+static void crypton_aes_cpu_ctor(void)
+{
+	crypton_aes_cpu_setup();
+}
+
+uint8_t *crypton_aes_cpu_init(void)
+{
 	return crypton_aes_cpu_options;
 }
 
@@ -443,7 +468,6 @@
 	case 24: key->nbr = 12; key->strength = 1; break;
 	case 32: key->nbr = 14; key->strength = 2; break;
 	}
-	crypton_aes_cpu_init();
 	init_f _init = GET_INIT(key->strength);
 	_init(key, origkey, size);
 }
diff --git a/cbits/crypton_align.h b/cbits/crypton_align.h
--- a/cbits/crypton_align.h
+++ b/cbits/crypton_align.h
@@ -3,6 +3,8 @@
 
 #include "crypton_bitfn.h"
 
+#include <string.h>
+
 #if (defined(__i386__))
 # define UNALIGNED_ACCESS_OK
 #elif defined(__x86_64__)
@@ -34,107 +36,119 @@
 #define need_alignment(p,n) IS_ALIGNED(p,n)
 #endif
 
-static inline uint32_t load_le32_aligned(const uint8_t *p)
-{
-	return le32_to_cpu(*((uint32_t *) p));		
-}
+/*
+ * Reading and writing a 32- or 64-bit word at a byte pointer.
+ *
+ * Through memcpy, not a cast to uint32_t * or uint64_t *.  A cast is two
+ * things the standard does not allow -- a read of the value through the
+ * wrong type, and a read at an address that type is not aligned for -- and
+ * this file used to do both wherever UNALIGNED_ACCESS_OK is defined, which
+ * is i386 and x86-64.  UndefinedBehaviorSanitizer reported seventy-eight
+ * lines of it.
+ *
+ * Every compiler crypton is built with turns a memcpy of four or eight bytes
+ * into the one load or store the cast used to be, so this is the same code
+ * with none of the licence.  Where the target cannot do an unaligned load,
+ * the compiler is the one that knows, and it emits what the target needs --
+ * which is what the byte-at-a-time versions this replaces were for.
+ *
+ * The _aligned names stay because nineteen files use them.  They no longer
+ * ask anything of the pointer.
+ */
 
-static inline void store_le32_aligned(uint8_t *dst, const uint32_t v)
+static inline uint32_t load_le32(const uint8_t *p)
 {
-	*((uint32_t *) dst) = cpu_to_le32(v);
-}
+	uint32_t v;
 
-static inline void xor_le32_aligned(uint8_t *dst, const uint32_t v)
-{
-	*((uint32_t *) dst) ^= cpu_to_le32(v);
+	memcpy(&v, p, sizeof(v));
+	return le32_to_cpu(v);
 }
 
-static inline void store_be32_aligned(uint8_t *dst, const uint32_t v)
+static inline uint64_t load_le64(const uint8_t *p)
 {
-	*((uint32_t *) dst) = cpu_to_be32(v);
-}
+	uint64_t v;
 
-static inline void xor_be32_aligned(uint8_t *dst, const uint32_t v)
-{
-	*((uint32_t *) dst) ^= cpu_to_be32(v);
+	memcpy(&v, p, sizeof(v));
+	return le64_to_cpu(v);
 }
 
-static inline void store_le64_aligned(uint8_t *dst, const uint64_t v)
+static inline uint32_t load_be32(const uint8_t *p)
 {
-	*((uint64_t *) dst) = cpu_to_le64(v);
-}
+	uint32_t v;
 
-static inline void store_be64_aligned(uint8_t *dst, const uint64_t v)
-{
-	*((uint64_t *) dst) = cpu_to_be64(v);
+	memcpy(&v, p, sizeof(v));
+	return be32_to_cpu(v);
 }
 
-static inline void xor_be64_aligned(uint8_t *dst, const uint64_t v)
+static inline uint64_t load_be64(const uint8_t *p)
 {
-	*((uint64_t *) dst) ^= cpu_to_be64(v);
-}
+	uint64_t v;
 
-#ifdef UNALIGNED_ACCESS_OK
-#define load_le32(a) load_le32_aligned(a)
-#else
-static inline uint32_t load_le32(const uint8_t *p)
-{
-	return ((uint32_t)p[0]) | ((uint32_t)p[1] <<  8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
+	memcpy(&v, p, sizeof(v));
+	return be64_to_cpu(v);
 }
-#endif
 
-#ifdef UNALIGNED_ACCESS_OK
-#define store_le32(a, b) store_le32_aligned(a, b)
-#define xor_le32(a, b) xor_le32_aligned(a, b)
-#else
 static inline void store_le32(uint8_t *dst, const uint32_t v)
 {
-	dst[0] = v; dst[1] = v >> 8; dst[2] = v >> 16; dst[3] = v >> 24;
+	uint32_t w = cpu_to_le32(v);
+
+	memcpy(dst, &w, sizeof(w));
 }
+
 static inline void xor_le32(uint8_t *dst, const uint32_t v)
 {
-	dst[0] ^= v; dst[1] ^= v >> 8; dst[2] ^= v >> 16; dst[3] ^= v >> 24;
+	store_le32(dst, le32_to_cpu(load_le32(dst)) ^ v);
 }
-#endif
 
-#ifdef UNALIGNED_ACCESS_OK
-#define store_be32(a, b) store_be32_aligned(a, b)
-#define xor_be32(a, b) xor_be32_aligned(a, b)
-#else
 static inline void store_be32(uint8_t *dst, const uint32_t v)
 {
-	dst[3] = v; dst[2] = v >> 8; dst[1] = v >> 16; dst[0] = v >> 24;
+	uint32_t w = cpu_to_be32(v);
+
+	memcpy(dst, &w, sizeof(w));
 }
+
 static inline void xor_be32(uint8_t *dst, const uint32_t v)
 {
-	dst[3] ^= v; dst[2] ^= v >> 8; dst[1] ^= v >> 16; dst[0] ^= v >> 24;
+	uint32_t w;
+
+	memcpy(&w, dst, sizeof(w));
+	w ^= cpu_to_be32(v);
+	memcpy(dst, &w, sizeof(w));
 }
-#endif
 
-#ifdef UNALIGNED_ACCESS_OK
-#define store_le64(a, b) store_le64_aligned(a, b)
-#else
 static inline void store_le64(uint8_t *dst, const uint64_t v)
 {
-	dst[0] = v      ; dst[1] = v >> 8 ; dst[2] = v >> 16; dst[3] = v >> 24;
-	dst[4] = v >> 32; dst[5] = v >> 40; dst[6] = v >> 48; dst[7] = v >> 56;
+	uint64_t w = cpu_to_le64(v);
+
+	memcpy(dst, &w, sizeof(w));
 }
-#endif
 
-#ifdef UNALIGNED_ACCESS_OK
-#define store_be64(a, b) store_be64_aligned(a, b)
-#define xor_be64(a, b) xor_be64_aligned(a, b)
-#else
 static inline void store_be64(uint8_t *dst, const uint64_t v)
 {
-	dst[7] = v      ; dst[6] = v >> 8 ; dst[5] = v >> 16; dst[4] = v >> 24;
-	dst[3] = v >> 32; dst[2] = v >> 40; dst[1] = v >> 48; dst[0] = v >> 56;
+	uint64_t w = cpu_to_be64(v);
+
+	memcpy(dst, &w, sizeof(w));
 }
+
 static inline void xor_be64(uint8_t *dst, const uint64_t v)
 {
-	dst[7] ^= v      ; dst[6] ^= v >> 8 ; dst[5] ^= v >> 16; dst[4] ^= v >> 24;
-	dst[3] ^= v >> 32; dst[2] ^= v >> 40; dst[1] ^= v >> 48; dst[0] ^= v >> 56;
+	uint64_t w;
+
+	memcpy(&w, dst, sizeof(w));
+	w ^= cpu_to_be64(v);
+	memcpy(dst, &w, sizeof(w));
 }
-#endif
+
+#define load_le32_aligned(p)     load_le32(p)
+#define load_le64_aligned(p)     load_le64(p)
+#define load_be32_aligned(p)     load_be32(p)
+#define load_be64_aligned(p)     load_be64(p)
+#define store_le32_aligned(d, v) store_le32(d, v)
+#define xor_le32_aligned(d, v)   xor_le32(d, v)
+#define store_be32_aligned(d, v) store_be32(d, v)
+#define xor_be32_aligned(d, v)   xor_be32(d, v)
+#define store_le64_aligned(d, v) store_le64(d, v)
+#define store_be64_aligned(d, v) store_be64(d, v)
+#define xor_be64_aligned(d, v)   xor_be64(d, v)
 
 #endif
diff --git a/cbits/crypton_bignum.h b/cbits/crypton_bignum.h
--- a/cbits/crypton_bignum.h
+++ b/cbits/crypton_bignum.h
@@ -112,9 +112,196 @@
 	return (limb_t) 0 - inv;
 }
 
-/* t += a * b over n limbs, returning the carry.  This is where nearly all of
- * the time goes, so the limbs are taken eight at a time; what is left over at
- * the end is taken one at a time. */
+/*
+ * t += a * b over n limbs, returning the carry.  This is where nearly all of
+ * the time goes.
+ *
+ * The C below takes the limbs eight at a time; what is left over at the end
+ * is taken one at a time.  On AArch64 the compiler writes each limb as
+ * `mul`, `umulh`, `adds`, `cset`, `adds`, `adc`: the carry out of one
+ * 128-bit addition leaves the flags for a general register and is added back
+ * in the next, because in C each addition is a statement of its own.  Two of
+ * those instructions are that round trip.
+ *
+ * Three attempts to take them back measured worse than the C, and are
+ * written down here so that they are not tried again -- one RSA-2048 CRT
+ * private operation on an Apple M4, best of many:
+ *
+ *     this loop in inline assembly, a carry chain per limb       654.7 us
+ *     the same with the loads hoisted out of the chain           644.5
+ *     the multiply interleaved with its reduction (CIOS)         604.1
+ *     the C below                                                590.1
+ *     what the AArch64 block does, four limbs and two chains     514.9
+ *     the same, with the ragged end of the row written out too   503.4
+ *
+ * The first two lose because a chain per limb serialises what the spare
+ * `cset` lets overlap: `adds`, `adc`, `adds`, `adc` is four dependent steps
+ * per limb, and a wide out-of-order core would rather have the extra
+ * instruction than the dependency.  The third loses because shifting the
+ * accumulator down a limb each round costs more than the round trip through
+ * 2n limbs that it saves.  What works is neither: four limbs to an
+ * iteration with the flags carrying through two long chains, one for the low
+ * halves of the products and one for the high halves a place up.
+ *
+ * There is more still there.  OpenSSL's armv8-mont.pl runs a 16-limb
+ * Montgomery multiplication at about 0.98 multiply-accumulates per cycle;
+ * this file was at 0.55 and the block below brings it to 0.64, where 1.0 is
+ * the ceiling -- a multiply-accumulate is two instructions and the machine
+ * issues two multiplies a cycle.  That code cannot be borrowed: it is in
+ * OpenSSL's tree only, under Apache-2.0, and CRYPTOGAMS, which this library
+ * does vendor from, publishes no Montgomery generator at all.  BearSSL's
+ * only ARM assembly is 32-bit Thumb for Cortex-M0 to M3, with fifteen-bit
+ * limbs for cores that have no fast multiplier, and Botan's AArch64 inline
+ * assembly is the `mul`/`umulh`/`adds`/`adc` primitive the compiler already
+ * emits.
+ */
+#if defined(__aarch64__) && LIMB_BITS == 64 \
+    && (defined(__GNUC__) || defined(__clang__))
+/*
+ * Four limbs to an iteration, accumulated in two chains rather than one per
+ * limb: the low halves of the four products, with the carry coming in, are
+ * one run of `adds` and `adcs`, and the high halves shifted up a place are
+ * another.  The flags carry the whole way through each, which is what the C
+ * above cannot say and what it pays for in `cset` and an extra add.
+ *
+ * The arrangement is the one in Go's crypto/internal/fips140/bigmod
+ * (nat_arm64.s, addMulVVWx), which is BSD-3-Clause like this library --
+ * cbits/LICENSE.go carries its notice.  Written out here in the assembler
+ * this file's compiler speaks.
+ */
+static inline limb_t addmul_1(limb_t *t, const limb_t *a, uint32_t n, limb_t b)
+{
+	uint64_t carry = 0;
+	uint64_t x0, x1, x2, x3, z0, z1, z2, z3;
+	uint64_t l0, l1, l2, l3, h0, h1, h2, h3;
+	uint64_t blocks = n / 4, left = n % 4;
+
+	if (blocks) {
+		__asm__ volatile(
+		"1:\n\t"
+		"ldp	%[x0], %[x1], [%[a]], #16\n\t"
+		"ldp	%[x2], %[x3], [%[a]], #16\n\t"
+		"ldp	%[z0], %[z1], [%[t]]\n\t"
+		/* the low halves, one place up from the second chain, with
+		 * the carry that came in */
+		"adds	%[z0], %[z0], %[c]\n\t"
+		"mul	%[l1], %[x1], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[l1]\n\t"
+		"mul	%[l2], %[x2], %[b]\n\t"
+		"ldp	%[z2], %[z3], [%[t], #16]\n\t"
+		"adcs	%[z2], %[z2], %[l2]\n\t"
+		"mul	%[l3], %[x3], %[b]\n\t"
+		"adcs	%[z3], %[z3], %[l3]\n\t"
+		"umulh	%[h3], %[x3], %[b]\n\t"
+		"adc	%[h3], %[h3], xzr\n\t"
+		/* and the high halves, which is where this block's own carry
+		 * ends up */
+		"mul	%[l0], %[x0], %[b]\n\t"
+		"adds	%[z0], %[z0], %[l0]\n\t"
+		"umulh	%[h0], %[x0], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[h0]\n\t"
+		"umulh	%[h1], %[x1], %[b]\n\t"
+		"stp	%[z0], %[z1], [%[t]], #16\n\t"
+		"adcs	%[z2], %[z2], %[h1]\n\t"
+		"umulh	%[h2], %[x2], %[b]\n\t"
+		"adcs	%[z3], %[z3], %[h2]\n\t"
+		"stp	%[z2], %[z3], [%[t]], #16\n\t"
+		"adc	%[c], %[h3], xzr\n\t"
+		"subs	%[k], %[k], #1\n\t"
+		"b.ne	1b\n\t"
+		: [a] "+r"(a), [t] "+r"(t), [c] "+r"(carry), [k] "+r"(blocks),
+		  [x0] "=&r"(x0), [x1] "=&r"(x1), [x2] "=&r"(x2),
+		  [x3] "=&r"(x3), [z0] "=&r"(z0), [z1] "=&r"(z1),
+		  [z2] "=&r"(z2), [z3] "=&r"(z3), [l0] "=&r"(l0),
+		  [l1] "=&r"(l1), [l2] "=&r"(l2), [l3] "=&r"(l3),
+		  [h0] "=&r"(h0), [h1] "=&r"(h1), [h2] "=&r"(h2),
+		  [h3] "=&r"(h3)
+		: [b] "r"(b)
+		: "cc", "memory");
+	}
+	/* What is left of the row: three limbs, two, or one, each the same two
+	 * chains cut short.  This is not a rare case to be handed back to C --
+	 * mont_sqr asks for every length from n-1 down to 1, so three rows in
+	 * four end ragged.  Only 4.7% of the limbs in a 1024-bit exponentiation
+	 * arrive here, but they were the dearer ones, and writing them out is
+	 * worth the last two per cent in the table above.  The three lengths
+	 * are spelled out rather than run as 2+1, because chaining two short
+	 * blocks makes the second wait on the first: that costs two thirds of
+	 * the gain.
+	 */
+	if (left == 3) {
+		__asm__ volatile(
+		"ldp	%[x0], %[x1], [%[a]]\n\t"
+		"ldr	%[x2], [%[a], #16]\n\t"
+		"add	%[a], %[a], #24\n\t"
+		"ldp	%[z0], %[z1], [%[t]]\n\t"
+		"ldr	%[z2], [%[t], #16]\n\t"
+		"adds	%[z0], %[z0], %[c]\n\t"
+		"mul	%[l1], %[x1], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[l1]\n\t"
+		"mul	%[l2], %[x2], %[b]\n\t"
+		"adcs	%[z2], %[z2], %[l2]\n\t"
+		"umulh	%[h2], %[x2], %[b]\n\t"
+		"adc	%[h2], %[h2], xzr\n\t"
+		"mul	%[l0], %[x0], %[b]\n\t"
+		"adds	%[z0], %[z0], %[l0]\n\t"
+		"umulh	%[h0], %[x0], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[h0]\n\t"
+		"umulh	%[h1], %[x1], %[b]\n\t"
+		"stp	%[z0], %[z1], [%[t]], #16\n\t"
+		"adcs	%[z2], %[z2], %[h1]\n\t"
+		"str	%[z2], [%[t]], #8\n\t"
+		"adc	%[c], %[h2], xzr\n\t"
+		: [a] "+r"(a), [t] "+r"(t), [c] "+r"(carry),
+		  [x0] "=&r"(x0), [x1] "=&r"(x1), [x2] "=&r"(x2),
+		  [z0] "=&r"(z0), [z1] "=&r"(z1), [z2] "=&r"(z2),
+		  [l0] "=&r"(l0), [l1] "=&r"(l1), [l2] "=&r"(l2),
+		  [h0] "=&r"(h0), [h1] "=&r"(h1), [h2] "=&r"(h2)
+		: [b] "r"(b)
+		: "cc", "memory");
+	} else if (left == 2) {
+		__asm__ volatile(
+		"ldp	%[x0], %[x1], [%[a]], #16\n\t"
+		"ldp	%[z0], %[z1], [%[t]]\n\t"
+		"adds	%[z0], %[z0], %[c]\n\t"
+		"mul	%[l1], %[x1], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[l1]\n\t"
+		"umulh	%[h1], %[x1], %[b]\n\t"
+		"adc	%[h1], %[h1], xzr\n\t"
+		"mul	%[l0], %[x0], %[b]\n\t"
+		"adds	%[z0], %[z0], %[l0]\n\t"
+		"umulh	%[h0], %[x0], %[b]\n\t"
+		"adcs	%[z1], %[z1], %[h0]\n\t"
+		"stp	%[z0], %[z1], [%[t]], #16\n\t"
+		"adc	%[c], %[h1], xzr\n\t"
+		: [a] "+r"(a), [t] "+r"(t), [c] "+r"(carry),
+		  [x0] "=&r"(x0), [x1] "=&r"(x1), [z0] "=&r"(z0),
+		  [z1] "=&r"(z1), [l0] "=&r"(l0), [l1] "=&r"(l1),
+		  [h0] "=&r"(h0), [h1] "=&r"(h1)
+		: [b] "r"(b)
+		: "cc", "memory");
+	} else if (left == 1) {
+		__asm__ volatile(
+		"ldr	%[x0], [%[a]], #8\n\t"
+		"ldr	%[z0], [%[t]]\n\t"
+		"mul	%[l0], %[x0], %[b]\n\t"
+		"adds	%[z0], %[z0], %[c]\n\t"
+		"umulh	%[h0], %[x0], %[b]\n\t"
+		"adc	%[h0], %[h0], xzr\n\t"
+		"adds	%[z0], %[z0], %[l0]\n\t"
+		"str	%[z0], [%[t]], #8\n\t"
+		"adc	%[c], %[h0], xzr\n\t"
+		: [a] "+r"(a), [t] "+r"(t), [c] "+r"(carry),
+		  [x0] "=&r"(x0), [z0] "=&r"(z0), [l0] "=&r"(l0),
+		  [h0] "=&r"(h0)
+		: [b] "r"(b)
+		: "cc", "memory");
+	}
+	return carry;
+}
+#else
+/* one limb of it, so that the loops below can say how many they take at a
+ * time without saying the rest of it four times over */
 #define ADDMUL_STEP(k)                                                  \
 	p = (dlimb_t) a[i + (k)] * b + t[i + (k)] + carry;                  \
 	t[i + (k)] = (limb_t) p;                                            \
@@ -141,6 +328,7 @@
 	}
 	return carry;
 }
+#endif
 
 /* r = t * R^-1 mod m, with t of 2n limbs and destroyed on the way */
 static inline void mont_reduce(limb_t *r, limb_t *t, const limb_t *m, limb_t n0,
@@ -165,14 +353,33 @@
 	select_n(r, r, t + n, take & 1, n);
 }
 
+/* t = a * b, the low n limbs, returning the limb above them: addmul_1 with
+ * nothing to add to, for the row of a product that lands on empty space. */
+static inline limb_t mul_1(limb_t *t, const limb_t *a, uint32_t n, limb_t b)
+{
+	limb_t carry = 0;
+	uint32_t i;
+
+	for (i = 0; i < n; i++) {
+		dlimb_t p = (dlimb_t) a[i] * b + carry;
+
+		t[i] = (limb_t) p;
+		carry = (limb_t) (p >> LIMB_BITS);
+	}
+	return carry;
+}
+
 /* r = a * b * R^-1 mod m, with t of 2n limbs */
 static inline void mont_mul(limb_t *r, const limb_t *a, const limb_t *b,
                      const limb_t *m, limb_t n0, uint32_t n, limb_t *t)
 {
 	uint32_t i;
 
-	memset(t, 0, 2 * n * sizeof(limb_t));
-	for (i = 0; i < n; i++)
+	/* Nothing has to be cleared first.  The first row lands on empty space
+	 * and writes t[0 .. n], and every row after it reads t[i .. i+n-1],
+	 * whose top limb is the one the row before it wrote. */
+	t[n] = mul_1(t, a, n, b[0]);
+	for (i = 1; i < n; i++)
 		t[n + i] = addmul_1(t + i, a, n, b[i]);
 	mont_reduce(r, t, m, n0, n);
 }
@@ -186,8 +393,14 @@
 	limb_t carry = 0;
 	uint32_t i;
 
-	memset(t, 0, 2 * n * sizeof(limb_t));
-	for (i = 0; i + 1 < n; i++)
+	/* The first row lands on empty space here too, on t[1 .. n], and the
+	 * rows between them write t[1 .. 2n-2] before any of it is read.  The
+	 * diagonal below is the only reader of the two ends. */
+	t[0] = 0;
+	t[2 * n - 1] = 0;
+	if (n > 1)
+		t[n] = mul_1(t + 1, a + 1, n - 1, a[0]);
+	for (i = 1; i + 1 < n; i++)
 		t[n + i] = addmul_1(t + i + i + 1, a + i + 1, n - 1 - i, a[i]);
 	shl1(t, 2 * n); /* their sum is under half of what 2n limbs hold */
 	for (i = 0; i < n; i++) {
@@ -201,15 +414,41 @@
 	mont_reduce(r, t, m, n0, n);
 }
 
-/* r2 = R^2 mod m, by doubling
+/* a = 2a mod m, for an a already under m */
+static inline void dbl_mod(limb_t *a, const limb_t *m, uint32_t n, limb_t *tmp)
+{
+	limb_t carry = shl1(a, n);
+	limb_t borrow = sub_n(tmp, a, m, n);
+
+	select_n(a, tmp, a, (carry | (borrow ^ 1)) & 1, n);
+}
+
+/* r2 = R^2 mod m, where R is 2^(n * LIMB_BITS)
  *
+ * Doubling the whole way there is 2n * LIMB_BITS steps, and at RSA sizes
+ * that is a tenth of the exponentiation it is setting up for.  Only the
+ * first half of it has to be done a bit at a time.
+ *
+ * Write a value as 2^(lgR + d) mod m.  A Montgomery squaring divides by R,
+ * so it takes that to 2(lgR + d) - lgR = lgR + 2d: it doubles d.  So double
+ * up to R mod m, where d is zero, take one more step to make d one, and then
+ * climb to d = lgR by the binary expansion of lgR -- a squaring for each bit
+ * and one more doubling where the bit is set.  For a 1024-bit modulus that
+ * is ten squarings in place of a thousand and twenty-five doublings, and on
+ * an Apple M4 that is 2.1 microseconds against 24.7.
+ *
  * Doubling starts at the highest power of two under the modulus rather than
  * at one, since everything below that power is where doubling would go
- * anyway: for a modulus that fills its limbs that is half the steps.
+ * anyway: for a modulus that fills its limbs, that first half is one step.
+ *
+ * What the trip counts depend on is the modulus' length, which is what the
+ * doubling loop showed as well, and nothing else about it.
  */
-static inline void mont_r2(limb_t *r2, const limb_t *m, uint32_t n, limb_t *tmp)
+static inline void mont_r2(limb_t *r2, const limb_t *m, limb_t n0, uint32_t n,
+                    limb_t *t)
 {
-	uint32_t i, k = 0, steps;
+	uint32_t lgr = n * LIMB_BITS;
+	uint32_t i, k = 0, msb = 0;
 
 	for (i = n; i > 0 && k == 0; i--)
 		if (m[i - 1] != 0) {
@@ -225,11 +464,16 @@
 	if (k == 0)
 		return; /* a modulus of nothing, which the caller rules out */
 	r2[(k - 1) / LIMB_BITS] = (limb_t) 1 << ((k - 1) % LIMB_BITS);
-	steps = 2 * n * LIMB_BITS - (k - 1);
-	for (i = 0; i < steps; i++) {
-		limb_t carry = shl1(r2, n);
-		limb_t borrow = sub_n(tmp, r2, m, n);
-		select_n(r2, tmp, r2, (carry | (borrow ^ 1)) & 1, n);
+	for (i = k - 1; i < lgr; i++)
+		dbl_mod(r2, m, n, t);
+	/* r2 is R mod m, so d is zero and squaring would leave it there */
+	dbl_mod(r2, m, n, t);
+	while ((lgr >> (msb + 1)) != 0)
+		msb++;
+	for (i = msb; i > 0; i--) {
+		mont_sqr(r2, r2, m, n0, n, t);
+		if ((lgr >> (i - 1)) & 1)
+			dbl_mod(r2, m, n, t);
 	}
 }
 
diff --git a/cbits/crypton_bzero.h b/cbits/crypton_bzero.h
new file mode 100644
--- /dev/null
+++ b/cbits/crypton_bzero.h
@@ -0,0 +1,27 @@
+/*
+ * Erasing memory that the compiler is entitled to decide nobody reads.
+ *
+ * memset on an object that is about to die -- freed, or a local going out of
+ * scope -- is a store to memory nothing can observe, and an optimizer may
+ * drop it.  That is the whole reason explicit_bzero and memset_s exist.
+ * Neither is everywhere, so this writes through a volatile pointer, which the
+ * standard says cannot be elided.
+ *
+ * Use it wherever key material stops being needed.  Plain memset is still
+ * right for memory that is about to be read again.
+ */
+#ifndef CRYPTON_BZERO_H
+#define CRYPTON_BZERO_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+static inline void crypton_bzero(void *p, size_t n)
+{
+	volatile uint8_t *q = (volatile uint8_t *)p;
+
+	while (n--)
+		*q++ = 0;
+}
+
+#endif
diff --git a/cbits/crypton_chacha.c b/cbits/crypton_chacha.c
--- a/cbits/crypton_chacha.c
+++ b/cbits/crypton_chacha.c
@@ -51,7 +51,7 @@
                                  const crypton_chacha_state *in);
 void crypton_chacha_simd_generate(int rounds, uint8_t *dst,
                                   const crypton_chacha_state *in);
-/* The counters in a group must not carry into d[13], which the block loop
+/* The counters in a group must not carry into d[13], which the crypton_chacha_block loop
  * below handles and the vector one does not; that is one run in 2^29. */
 #define CHACHA_SIMD_OK(st, n) ((st)->d[12] <= 0xffffffffU - (uint32_t) (n))
 #endif
@@ -89,7 +89,7 @@
  * How much is worth handing over.  On AArch64 the module's vector path
  * starts at three blocks and below that its scalar path measures level with
  * the C here, so there is nothing to gain; on x86-64 it is ahead from one
- * block, the C there having no vector path until eight.
+ * crypton_chacha_block, the C there having no vector path until eight.
  */
 #ifndef CHACHA_ASM_MIN_BLOCKS
 #ifdef WITH_X86_CHACHA_ASM
@@ -112,7 +112,7 @@
 static const uint8_t sigma[16] = "expand 32-byte k";
 static const uint8_t tau[16] = "expand 16-byte k";
 
-static void chacha_core(int rounds, block *out, const crypton_chacha_state *in)
+static void chacha_core(int rounds, crypton_chacha_block *out, const crypton_chacha_state *in)
 {
 	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
 	int i;
@@ -296,7 +296,7 @@
 
 void crypton_chacha_combine(uint8_t *dst, crypton_chacha_context *ctx, const uint8_t *src, uint32_t bytes)
 {
-	block out;
+	crypton_chacha_block out;
 	crypton_chacha_state *st;
 	int i;
 
@@ -434,7 +434,7 @@
 void crypton_chacha_generate(uint8_t *dst, crypton_chacha_context *ctx, uint32_t bytes)
 {
 	crypton_chacha_state *st;
-	block out;
+	crypton_chacha_block out;
 	int i;
 
 	if (!bytes)
@@ -474,7 +474,7 @@
 		/* xor new 64-bytes chunks and store the left over if any */
 		for (; bytes >= 64; bytes -= 64, dst += 64) {
 			/* generate new chunk and update state */
-			chacha_core(ctx->nb_rounds, (block *) dst, st);
+			chacha_core(ctx->nb_rounds, (crypton_chacha_block *) dst, st);
 			uint32_t t0 = le32_to_cpu(st->d[12]);
 			st->d[12] = cpu_to_le32(t0 + 1);
 			if (st->d[12] == 0) {
@@ -524,9 +524,9 @@
 void crypton_chacha_generate_simple_block(uint8_t *dst, crypton_chacha_state *st, uint8_t rounds)
 {
 	if (ALIGNED64(dst)) {
-		chacha_core(rounds, (block *) dst, st);
+		chacha_core(rounds, (crypton_chacha_block *) dst, st);
 	} else {
-		block out;
+		crypton_chacha_block out;
 		int i;
 		chacha_core(rounds, &out, st);
 		for (i = 0; i < 64; ++i) {
@@ -544,7 +544,7 @@
 
 void crypton_chacha_random(uint32_t rounds, uint8_t *dst, crypton_chacha_state *st, uint32_t bytes)
 {
-	block out;
+	crypton_chacha_block out;
 
 	if (!bytes)
 		return;
diff --git a/cbits/crypton_chacha.h b/cbits/crypton_chacha.h
--- a/cbits/crypton_chacha.h
+++ b/cbits/crypton_chacha.h
@@ -34,9 +34,9 @@
 	uint64_t q[8];
 	uint32_t d[16];
 	uint8_t  b[64];
-} block;
+} crypton_chacha_block;
 
-typedef block crypton_chacha_state;
+typedef crypton_chacha_block crypton_chacha_state;
 
 typedef struct {
 	crypton_chacha_state st;
diff --git a/cbits/crypton_cpu.c b/cbits/crypton_cpu.c
--- a/cbits/crypton_cpu.c
+++ b/cbits/crypton_cpu.c
@@ -182,13 +182,23 @@
 	static uint32_t features = 0;
 
 	if (!resolved) {
-		uint32_t eax, ebx, ecx, edx, leaf1, maxleaf, f = 0;
+		uint32_t eax, ebx, ecx, edx, leaf1, maxleaf, family, f = 0;
+		int amd;
 
 		cpuid(0, &eax, &ebx, &ecx, &edx);
 		maxleaf = eax;
+		/* "AuthenticAMD" arrives as EBX, EDX, ECX in that order */
+		amd = (ebx == 0x68747541 && edx == 0x69746e65
+		       && ecx == 0x444d4163);
 
 		cpuid(1, &eax, &ebx, &ecx, &edx);
 		leaf1 = ecx;
+		/* the family is the base one, and the extended field is
+		 * added to it only when the base reads 0xf, which is how
+		 * every AMD Zen part reports */
+		family = (eax >> 8) & 0xf;
+		if (family == 0xf)
+			family += (eax >> 20) & 0xff;
 		if (leaf1 & (1 << 9))
 			f |= CRYPTON_X86_SSSE3;
 		if (leaf1 & (1 << 1))
@@ -236,6 +246,29 @@
 			if ((ecx & (1 << 9)) && (ecx & (1 << 10))
 			    && (f & CRYPTON_X86_AVX2))
 				f |= CRYPTON_X86_VAES;
+			/* The same two instructions in their 512-bit form,
+			 * which wants AVX-512 F, BW and VL as well -- and
+			 * three more bits of XCR0, for the mask registers and
+			 * the two upper halves of the vector state.  A
+			 * machine can report the instructions and still fault
+			 * on them when the operating system has not said it
+			 * saves that state, which is what those bits are. */
+			if ((f & CRYPTON_X86_VAES)
+			    && (ebx & (1 << 16)) && (ebx & (1u << 30))
+			    && (ebx & (1u << 31))
+			    && ((xcr0() & 0xe6) == 0xe6)
+			    /* Not on Zen 4, which is AMD family 19h with
+			     * AVX-512: there the 512-bit instructions are two
+			     * 256-bit passes through a 256-bit datapath, so
+			     * they carry the wider encoding for none of the
+			     * throughput, and AES-GCM measures 0.6 to 3
+			     * per cent slower than the 256-bit path.  Zen 5
+			     * is family 1Ah and does have the wide datapath,
+			     * where the same code is half as fast again;
+			     * Zen 3, the other family 19h part, has no
+			     * AVX-512 at all and never reaches here. */
+			    && !(amd && family == 0x19))
+				f |= CRYPTON_X86_VAES512;
 		}
 		features = f;
 		resolved = 1;
diff --git a/cbits/crypton_cpu.h b/cbits/crypton_cpu.h
--- a/cbits/crypton_cpu.h
+++ b/cbits/crypton_cpu.h
@@ -60,6 +60,11 @@
  * they ask nothing further of it -- but AVX2 itself is asked about, since
  * without it there is nowhere to put them. */
 #define CRYPTON_X86_VAES   128
+/* The same pair in their 512-bit form, four blocks to an instruction.  These
+ * are EVEX-encoded and need the AVX-512 state as well, which is three more
+ * bits of XCR0 than AVX2 wants: the mask registers and the two upper halves
+ * of the vector registers. */
+#define CRYPTON_X86_VAES512 256
 #ifdef ARCH_X86
 uint32_t crypton_x86_simd_features(void);
 #endif
diff --git a/cbits/crypton_ecc.c b/cbits/crypton_ecc.c
--- a/cbits/crypton_ecc.c
+++ b/cbits/crypton_ecc.c
@@ -23,6 +23,7 @@
  */
 #include <stdlib.h>
 #include <crypton_bignum.h>
+#include <crypton_bzero.h>
 #include <crypton_ecc.h>
 #include <crypton_powm.h>
 #ifdef CRYPTON_S2N_BIGNUM
@@ -223,12 +224,15 @@
 
 static void ctx_free(curve_ctx *c)
 {
+	/* crypton_bzero rather than memset: this memory is freed on the next
+	 * line, and a store to memory about to die is one an optimizer may
+	 * drop.  Both buffers have held scalars. */
 	if (c->space != NULL) {
-		memset(c->space, 0, c->words * sizeof(limb_t));
+		crypton_bzero(c->space, c->words * sizeof(limb_t));
 		free(c->space);
 	}
 	if (c->bytes != NULL) {
-		memset(c->bytes, 0, 2 * c->plen);
+		crypton_bzero(c->bytes, 2 * c->plen);
 		free(c->bytes);
 	}
 	c->space = NULL;
@@ -287,10 +291,10 @@
 		ctx_free(c);
 		return -1;
 	}
-	mont_r2(c->r2, mp, n, mont_t);
+	c->f.n0 = mont_n0(mp[0]);
+	mont_r2(c->r2, mp, c->f.n0, n, mont_t);
 
 	c->f.n = n;
-	c->f.n0 = mont_n0(mp[0]);
 	c->f.p = mp;
 	c->f.a = ma;
 	c->f.b3 = mb3;
diff --git a/cbits/crypton_f2m.c b/cbits/crypton_f2m.c
--- a/cbits/crypton_f2m.c
+++ b/cbits/crypton_f2m.c
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <crypton_cpu.h>
+#include <crypton_bzero.h>
 #include <crypton_f2m.h>
 
 typedef uint64_t limb_t;
@@ -543,8 +544,10 @@
 	ret = 0;
 
 done:
+	/* freed on the next line, so a plain memset here is a store the
+	 * optimizer may drop */
 	if (space != NULL) {
-		memset(space, 0, words * sizeof(limb_t));
+		crypton_bzero(space, words * sizeof(limb_t));
 		free(space);
 	}
 	return ret;
diff --git a/cbits/crypton_md4.c b/cbits/crypton_md4.c
--- a/cbits/crypton_md4.c
+++ b/cbits/crypton_md4.c
@@ -48,16 +48,17 @@
 #define K3 	0x6ED9EBA1
 #define R(a,b,c,d,f,k,s,i) (a = rol32(a + f(b,c,d) + w[i] + k, s))
 
-static void md4_do_chunk(struct md4_ctx *ctx, uint32_t *buf)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static void md4_do_chunk(struct md4_ctx *ctx, const uint8_t *buf)
 {
 	uint32_t a, b, c, d;
-#ifdef ARCH_IS_BIG_ENDIAN
 	uint32_t w[16];
-	cpu_to_le32_array(w, (uint32_t *) buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
+	int wi;
 
+	for (wi = 0; wi < 16; wi++)
+		w[wi] = load_le32(buf + 4 * wi);
+
 	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
 
 	R(a, b, c, d, f1, K1, 3, 0);
@@ -125,24 +126,15 @@
 
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		md4_do_chunk(ctx, (uint32_t *) ctx->buf);
+		md4_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
 	}
 
-	if (need_alignment(data, 4)) {
-		uint32_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 4);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			md4_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			md4_do_chunk(ctx, (uint32_t *) data);
-	}
+	/* No trampoline: load_le32 does not ask for a boundary. */
+	for (; len >= 64; len -= 64, data += 64)
+		md4_do_chunk(ctx, data);
 
 	/* append data into buf */
 	if (len)
diff --git a/cbits/crypton_md5.c b/cbits/crypton_md5.c
--- a/cbits/crypton_md5.c
+++ b/cbits/crypton_md5.c
@@ -45,15 +45,22 @@
 #define f4(x, y, z)	(y ^ (x | ~z))
 #define R(f, a, b, c, d, i, k, s) a += f(b, c, d) + w[i] + k; a = rol32(a, s); a += b
 
-static void md5_do_chunk(struct md5_ctx *ctx, uint32_t *buf)
+/* The sixteen words are read out of the block rather than the block being
+ * pointed at as though it were an array of them.  A caller's pointer cast to
+ * uint32_t * is a pointer the standard says may not exist unless the address
+ * is aligned for it, and reading through it is undefined whether or not the
+ * machine minds; UndefinedBehaviorSanitizer counted sixty-four of these.
+ * load_le32 is a memcpy, which every compiler here turns into the one load
+ * the cast used to be, and it takes the endianness with it -- so the two
+ * arms this replaces are one. */
+static void md5_do_chunk(struct md5_ctx *ctx, const uint8_t *buf)
 {
 	uint32_t a, b, c, d;
-#ifdef ARCH_IS_BIG_ENDIAN
 	uint32_t w[16];
-	cpu_to_le32_array(w, buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
+	int wi;
+
+	for (wi = 0; wi < 16; wi++)
+		w[wi] = load_le32(buf + 4 * wi);
 	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
 
 	R(f1, a, b, c, d, 0, 0xd76aa478, 7);
@@ -138,24 +145,16 @@
 
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		md5_do_chunk(ctx, (uint32_t *) ctx->buf);
+		md5_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
 	}
 
-	if (need_alignment(data, 4)) {
-		uint32_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 4);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			md5_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			md5_do_chunk(ctx, (uint32_t *) data);
-	}
+	/* No trampoline for a block that is not on a four-byte boundary: the
+	 * words are read with load_le32 now, which does not ask. */
+	for (; len >= 64; len -= 64, data += 64)
+		md5_do_chunk(ctx, data);
 
 	/* append data into buf */
 	if (len)
diff --git a/cbits/crypton_powm.c b/cbits/crypton_powm.c
--- a/cbits/crypton_powm.c
+++ b/cbits/crypton_powm.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <crypton_bignum.h>
 #include <crypton_powm.h>
+#include <crypton_bzero.h>
 
 /*
  * At RSA sizes on x86-64, the Montgomery multiplication below is the whole
@@ -125,11 +126,85 @@
 	mont_sqr(r, a, m, n0, n, t);
 }
 
-/* four bits of exponent per window, so a table of sixteen and no leftover
- * bits: a byte holds exactly two windows */
+/* Four bits of exponent per window, so a table of sixteen and no leftover
+ * bits: a byte holds exactly two windows.
+ *
+ * Five was written and measured, and is not here.  A wider window saves
+ * multiplications -- 205 of them against 256 at 1024 bits, with the same
+ * 1024 squarings -- and pays for it in the masked scan of a table twice as
+ * long, and which way that comes out depends on the machine and on which
+ * multiplication is running: 3.5% better on an Apple M4, about 1% worse on
+ * an older x86-64, and 7% worse anywhere s2n-bignum's multiplication is
+ * used, since that makes the scan the expensive half.  Six measured level
+ * with five on the M4 and seven worse.  What would make a wider window pay
+ * everywhere is a cheaper scan, not a wider window. */
 #define WINDOW_BITS 4
 #define TABLE_SIZE (1 << WINDOW_BITS)
 
+/* The masked scan of the table: every entry is read and a mask keeps the one
+ * wanted, so that the address stream does not follow the exponent.  At
+ * RSA-2048's CRT size that is two kilobytes read per window, and the window
+ * loop runs 256 times per exponentiation, which is why it is worth a vector
+ * register: removing the scan altogether measures 11% of an exponentiation
+ * where s2n-bignum's multiplication runs, and the AVX2 form below gets
+ * essentially all of it. */
+static void scan_table(limb_t *sel, const limb_t *table, uint32_t n, limb_t w)
+{
+	uint32_t k, l;
+
+	memset(sel, 0, n * sizeof(limb_t));
+	for (k = 0; k < TABLE_SIZE; k++) {
+		limb_t mask = eq_mask(k, w);
+
+		for (l = 0; l < n; l++)
+			sel[l] |= table[k * n + l] & mask;
+	}
+}
+
+#if defined(__x86_64__) && defined(WITH_TARGET_ATTRIBUTES) && LIMB_BITS == 64
+#define CRYPTON_POWM_SCAN_AVX2 1
+#include <crypton_cpu.h>
+#include <immintrin.h>
+
+/* The same scan four limbs at a time.  The sixteen masks are worked out
+ * once; after that each register of the answer is one pass over the table's
+ * column, reading every entry exactly as the scalar form does. */
+__attribute__((target("avx2")))
+static void scan_table_avx2(limb_t *sel, const limb_t *table, uint32_t n,
+                            limb_t w)
+{
+	__m256i masks[TABLE_SIZE];
+	uint32_t k, l;
+
+	for (k = 0; k < TABLE_SIZE; k++)
+		masks[k] = _mm256_cmpeq_epi64(
+			_mm256_set1_epi64x((long long) k),
+			_mm256_set1_epi64x((long long) w));
+
+	for (l = 0; l + 4 <= n; l += 4) {
+		__m256i acc = _mm256_setzero_si256();
+
+		for (k = 0; k < TABLE_SIZE; k++) {
+			__m256i v = _mm256_loadu_si256(
+				(const __m256i *) (table + k * n + l));
+
+			acc = _mm256_or_si256(acc,
+			                      _mm256_and_si256(v, masks[k]));
+		}
+		_mm256_storeu_si256((__m256i *) (sel + l), acc);
+	}
+
+	/* a modulus whose limbs do not come in fours ends here */
+	for (; l < n; l++) {
+		limb_t v = 0;
+
+		for (k = 0; k < TABLE_SIZE; k++)
+			v |= table[k * n + l] & eq_mask(k, w);
+		sel[l] = v;
+	}
+}
+#endif
+
 int crypton_powm_sec(uint8_t *out,
                      const uint8_t *base, uint32_t baselen,
                      const uint8_t *exp, uint32_t explen,
@@ -140,6 +215,9 @@
 	limb_t *space, *m, *r2, *acc, *sel, *prod, *table, *t, *scratch, n0;
 	uint32_t i, j, k;
 	int s2n = 0;
+#ifdef CRYPTON_POWM_SCAN_AVX2
+	int avx2 = (crypton_x86_simd_features() & CRYPTON_X86_AVX2) != 0;
+#endif
 
 	if (modlen == 0 || n == 0 || (mod[modlen - 1] & 1) == 0)
 		return 1;
@@ -163,8 +241,8 @@
 
 	if (from_be(m, n, mod, modlen) != 0)
 		goto fail;
-	mont_r2(r2, m, n, t);
 	n0 = mont_n0(m[0]);
+	mont_r2(r2, m, n0, n, t);
 
 	/* table[k] = base^k in Montgomery form, and table[0] = 1 there */
 	memset(table, 0, n * sizeof(limb_t));
@@ -185,22 +263,31 @@
 		uint32_t nib = i - 1;
 		limb_t w = (exp[explen - 1 - nib / 2] >> (4 * (nib % 2))) & 0xf;
 
+		/* squaring into the other buffer and swapping the two saves a
+		 * copy of the modulus' width every time; which of the three
+		 * buffers a pointer names is nobody's secret */
 		for (j = 0; j < WINDOW_BITS; j++) {
+			limb_t *swap;
+
 			powm_sqr(sel, acc, m, n0, n, t, scratch, s2n);
-			memcpy(acc, sel, n * sizeof(limb_t));
+			swap = acc;
+			acc = sel;
+			sel = swap;
 		}
 
-		/* every entry is read, and a mask keeps the one wanted */
-		memset(sel, 0, n * sizeof(limb_t));
-		for (k = 0; k < TABLE_SIZE; k++) {
-			limb_t mask = eq_mask(k, w);
-			uint32_t l;
+#ifdef CRYPTON_POWM_SCAN_AVX2
+		if (avx2)
+			scan_table_avx2(sel, table, n, w);
+		else
+#endif
+			scan_table(sel, table, n, w);
+		powm_mul(prod, acc, sel, m, n0, n, t, scratch, s2n);
+		{
+			limb_t *swap = acc;
 
-			for (l = 0; l < n; l++)
-				sel[l] |= table[k * n + l] & mask;
+			acc = prod;
+			prod = swap;
 		}
-		powm_mul(prod, acc, sel, m, n0, n, t, scratch, s2n);
-		memcpy(acc, prod, n * sizeof(limb_t));
 	}
 
 	/* out of Montgomery form */
@@ -210,13 +297,15 @@
 	to_be(out, modlen, prod, n);
 
 	/* nothing here is the caller's secret, but the exponent's bits passed
-	 * through the accumulators */
-	memset(space, 0, words * sizeof(limb_t));
+	 * through the accumulators.  crypton_bzero rather than memset, since
+	 * this memory is freed on the next line and a store to memory about to
+	 * die is one an optimizer may drop. */
+	crypton_bzero(space, words * sizeof(limb_t));
 	free(space);
 	return 0;
 
 fail:
-	memset(space, 0, words * sizeof(limb_t));
+	crypton_bzero(space, words * sizeof(limb_t));
 	free(space);
 	return 1;
 }
diff --git a/cbits/crypton_ripemd.c b/cbits/crypton_ripemd.c
--- a/cbits/crypton_ripemd.c
+++ b/cbits/crypton_ripemd.c
@@ -57,16 +57,17 @@
 #define R(a, b, c, d, e, f, k, i, s)	\
 	a += f(b, c, d) + w[i] + k; a = rol32(a, s) + e; c = rol32(c, 10)
 
-static void ripemd160_do_chunk(struct ripemd160_ctx *ctx, uint32_t *buf)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static void ripemd160_do_chunk(struct ripemd160_ctx *ctx, const uint8_t *buf)
 {
 	uint32_t a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
-#ifdef ARCH_IS_BIG_ENDIAN
 	uint32_t w[16];
-	cpu_to_le32_array(w, buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
+	int wi;
 
+	for (wi = 0; wi < 16; wi++)
+		w[wi] = load_le32(buf + 4 * wi);
+
 	a1 = ctx->h[0]; b1 = ctx->h[1]; c1 = ctx->h[2]; d1 = ctx->h[3]; e1 = ctx->h[4];
 	a2 = ctx->h[0]; b2 = ctx->h[1]; c2 = ctx->h[2]; d2 = ctx->h[3]; e2 = ctx->h[4];
 
@@ -260,24 +261,15 @@
 	ctx->sz += len;
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		ripemd160_do_chunk(ctx, (uint32_t *) ctx->buf);
+		ripemd160_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
 	}
 
-	if (need_alignment(data, 4)) {
-		uint32_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 4);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			ripemd160_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			ripemd160_do_chunk(ctx, (uint32_t *) data);
-	}
+	/* No trampoline: load_le32 does not ask for a boundary. */
+	for (; len >= 64; len -= 64, data += 64)
+		ripemd160_do_chunk(ctx, data);
 
 	/* append data into buf */
 	if (len)
diff --git a/cbits/crypton_salsa.c b/cbits/crypton_salsa.c
--- a/cbits/crypton_salsa.c
+++ b/cbits/crypton_salsa.c
@@ -59,7 +59,7 @@
 		QR (x15,x12,x13,x14); \
 	}
 
-static void salsa_core(int rounds, block *out, const crypton_salsa_state *in)
+static void salsa_core(int rounds, crypton_salsa_block *out, const crypton_salsa_state *in)
 {
 	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
 	int i;
@@ -94,7 +94,7 @@
 	out->d[15] = cpu_to_le32(x15);
 }
 
-void crypton_salsa_core_xor(int rounds, block *out, block *in)
+void crypton_salsa_core_xor(int rounds, crypton_salsa_block *out, crypton_salsa_block *in)
 {
 	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
 	int i;
@@ -165,7 +165,7 @@
 
 void crypton_salsa_combine(uint8_t *dst, crypton_salsa_context *ctx, const uint8_t *src, uint32_t bytes)
 {
-	block out;
+	crypton_salsa_block out;
 	crypton_salsa_state *st;
 	int i;
 
@@ -225,7 +225,7 @@
 void crypton_salsa_generate(uint8_t *dst, crypton_salsa_context *ctx, uint32_t bytes)
 {
 	crypton_salsa_state *st;
-	block out;
+	crypton_salsa_block out;
 	int i;
 
 	if (!bytes)
@@ -252,7 +252,7 @@
 		/* xor new 64-bytes chunks and store the left over if any */
 		for (; bytes >= 64; bytes -= 64, dst += 64) {
 			/* generate new chunk and update state */
-			salsa_core(ctx->nb_rounds, (block *) dst, st);
+			salsa_core(ctx->nb_rounds, (crypton_salsa_block *) dst, st);
 			st->d[8] += 1;
 			if (st->d[8] == 0)
 				st->d[9] += 1;
diff --git a/cbits/crypton_salsa.h b/cbits/crypton_salsa.h
--- a/cbits/crypton_salsa.h
+++ b/cbits/crypton_salsa.h
@@ -34,9 +34,9 @@
 	uint64_t q[8];
 	uint32_t d[16];
 	uint8_t  b[64];
-} block;
+} crypton_salsa_block;
 
-typedef block crypton_salsa_state;
+typedef crypton_salsa_block crypton_salsa_state;
 
 typedef struct {
 	crypton_salsa_state st;
@@ -47,7 +47,7 @@
 } crypton_salsa_context;
 
 /* for scrypt */
-void crypton_salsa_core_xor(int rounds, block *out, block *in);
+void crypton_salsa_core_xor(int rounds, crypton_salsa_block *out, crypton_salsa_block *in);
 
 void crypton_salsa_init_core(crypton_salsa_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv);
 void crypton_salsa_init(crypton_salsa_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv);
diff --git a/cbits/crypton_scrypt.c b/cbits/crypton_scrypt.c
--- a/cbits/crypton_scrypt.c
+++ b/cbits/crypton_scrypt.c
@@ -37,10 +37,10 @@
 	array_copy32(X, &in[(2 * r - 1) * 16], 16);
 
 	for (i = 0; i < 2 * r; i += 2) {
-		crypton_salsa_core_xor(8, (block *) X, (block *) &in[i*16]);
+		crypton_salsa_core_xor(8, (crypton_salsa_block *) X, (crypton_salsa_block *) &in[i*16]);
 		array_copy32(&out[i * 8], X, 16);
 
-		crypton_salsa_core_xor(8, (block *) X, (block *) &in[i*16+16]);
+		crypton_salsa_core_xor(8, (crypton_salsa_block *) X, (crypton_salsa_block *) &in[i*16+16]);
 		array_copy32(&out[i * 8 + r * 16], X, 16);
 	}
 }
diff --git a/cbits/crypton_sha1.c b/cbits/crypton_sha1.c
--- a/cbits/crypton_sha1.c
+++ b/cbits/crypton_sha1.c
@@ -32,7 +32,7 @@
  * Two threads racing to answer here both write the same value.
  */
 #ifdef WITH_ARMV8_SHA1
-extern void crypton_sha1_armv8_do_chunk(uint32_t state[5], const uint32_t buf[16]);
+extern void crypton_sha1_armv8_do_chunk(uint32_t state[5], const uint8_t buf[64]);
 extern void crypton_sha1_armv8_do_chunks(uint32_t state[5], const uint8_t *data,
                                          uint32_t blocks);
 extern int crypton_sha1_armv8_available(void);
@@ -55,8 +55,20 @@
                                               const void *data, size_t blocks);
 #endif
 
+/* Resolved before there is a second thread; see the constructor in
+ * cbits/crypton_aes.c for why.  The test below then only ever reads. */
 static int sha1_use_armv8 = -1;
+
+__attribute__((constructor))
+static void sha1_armv8_ctor(void)
+{
+	sha1_use_armv8 = crypton_sha1_armv8_available();
+#ifdef SHA1_ASM
+	if (sha1_use_armv8)
+		crypton_armcap_P |= CRYPTON_ARMCAP_SHA1;
 #endif
+}
+#endif
 
 #ifdef WITH_X86_SHA_NI
 #include "crypton_cpu.h"
@@ -89,11 +101,13 @@
 #define M(i)  (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \
               ^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1))
 
-static void sha1_do_chunk_generic(struct sha1_ctx *ctx, uint32_t *buf)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static void sha1_do_chunk_generic(struct sha1_ctx *ctx, const uint8_t *buf)
 {
 	uint32_t a, b, c, d, e;
 	uint32_t w[16];
-#define CPY(i)	w[i] = be32_to_cpu(buf[i])
+#define CPY(i)	w[i] = load_be32(buf + 4 * (i))
 	CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7);
 	CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15);
 #undef CPY
@@ -204,7 +218,7 @@
 static int sha1_use_x86 = -1;
 #endif
 
-static inline void sha1_do_chunk(struct sha1_ctx *ctx, uint32_t *buf)
+static inline void sha1_do_chunk(struct sha1_ctx *ctx, const uint8_t *buf)
 {
 #ifdef WITH_ARMV8_SHA1
 	if (sha1_use_armv8 < 0) {
@@ -247,7 +261,7 @@
 	/* process partial buffer if there's enough data to make a block */
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		sha1_do_chunk(ctx, (uint32_t *) ctx->buf);
+		sha1_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
@@ -292,18 +306,9 @@
 	}
 #endif
 
-	if (need_alignment(data, 4)) {
-		uint32_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 4);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			sha1_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			sha1_do_chunk(ctx, (uint32_t *) data);
-	}
+	/* No trampoline: load_be32 does not ask for a boundary. */
+	for (; len >= 64; len -= 64, data += 64)
+		sha1_do_chunk(ctx, data);
 
 	/* append data into buf */
 	if (len)
diff --git a/cbits/crypton_sha256.c b/cbits/crypton_sha256.c
--- a/cbits/crypton_sha256.c
+++ b/cbits/crypton_sha256.c
@@ -78,13 +78,16 @@
 #define s0(x)       (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
 #define s1(x)       (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
 
-static void sha256_do_chunk_generic(struct sha256_ctx *ctx, uint32_t buf[])
+/* The sixteen words are read out of the block rather than the block being
+ * pointed at as though it were an array of them; see crypton_md5.c. */
+static void sha256_do_chunk_generic(struct sha256_ctx *ctx, const uint8_t *buf)
 {
 	uint32_t a, b, c, d, e, f, g, h, t1, t2;
 	int i;
 	uint32_t w[64];
 
-	cpu_to_be32_array(w, buf, 16);
+	for (i = 0; i < 16; i++)
+		w[i] = load_be32(buf + 4 * i);
 	for (i = 16; i < 64; i++)
 		w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
 
@@ -120,10 +123,18 @@
  * sha256_armv8.c.  They are optional in ARMv8.0, so ask before using them.
  * Two threads racing to answer here both write the same value.
  */
-extern void crypton_sha256_armv8_do_chunk(uint32_t state[8], const uint32_t buf[16]);
+extern void crypton_sha256_armv8_do_chunk(uint32_t state[8], const uint8_t buf[64]);
 extern int crypton_sha256_armv8_available(void);
 
+/* Resolved before there is a second thread; see the constructor in
+ * cbits/crypton_aes.c for why.  The test below then only ever reads. */
 static int sha256_use_armv8 = -1;
+
+__attribute__((constructor))
+static void sha256_armv8_ctor(void)
+{
+	sha256_use_armv8 = crypton_sha256_armv8_available();
+}
 #endif
 
 #if (defined(WITH_ARMV8_SHA256_ASM) && defined(WITH_ARMV8_SHA2)) \
@@ -156,7 +167,7 @@
 #endif
 
 
-static void sha256_do_chunk(struct sha256_ctx *ctx, uint32_t buf[])
+static void sha256_do_chunk(struct sha256_ctx *ctx, const uint8_t *buf)
 {
 #ifdef SHA256_ASM
 	sha256_asm_ready();
@@ -192,7 +203,7 @@
 	/* process partial buffer if there's enough data to make a block */
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		sha256_do_chunk(ctx, (uint32_t *) ctx->buf);
+		sha256_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
@@ -211,18 +222,9 @@
 		len -= (uint32_t) blocks * 64;
 	}
 #else
-	if (need_alignment(data, 4)) {
-		uint32_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 4);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			sha256_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			sha256_do_chunk(ctx, (uint32_t *) data);
-	}
+	/* No trampoline: load_be32 does not ask for a boundary. */
+	for (; len >= 64; len -= 64, data += 64)
+		sha256_do_chunk(ctx, data);
 #endif
 
 	/* append data into buf */
diff --git a/cbits/crypton_sha3.c b/cbits/crypton_sha3.c
--- a/cbits/crypton_sha3.c
+++ b/cbits/crypton_sha3.c
@@ -102,14 +102,16 @@
 #define sha3_asm_absorb crypton_keccak_asm_absorb
 #endif
 
-static inline void sha3_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static inline void sha3_do_chunk(uint64_t state[25], const uint8_t *buf, int bufsz)
 {
 	int i, j, r;
 	uint64_t tmp, bc[5];
 
 	/* merge buf with state */
 	for (i = 0; i < bufsz; i++)
-		state[i] ^= le64_to_cpu(buf[i]);
+		state[i] ^= load_le64(buf + 8 * i);
 
 #ifdef WITH_ARMV8_SHA3
 	if (sha3_armv8_ok()) {
@@ -180,14 +182,14 @@
 	to_fill = ctx->bufsz - ctx->bufindex;
 
 	if (ctx->bufindex == ctx->bufsz) {
-		sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
+		sha3_do_chunk(ctx->state, ctx->buf, ctx->bufsz / 8);
 		ctx->bufindex = 0;
 	}
 
 	/* process partial buffer if there's enough data to make a block */
 	if (ctx->bufindex && len >= to_fill) {
 		memcpy(ctx->buf + ctx->bufindex, data, to_fill);
-		sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
+		sha3_do_chunk(ctx->state, ctx->buf, ctx->bufsz / 8);
 		len -= to_fill;
 		data += to_fill;
 		ctx->bufindex = 0;
@@ -207,18 +209,9 @@
 	}
 #endif
 
-	if (need_alignment(data, 8)) {
-		uint64_t tramp[SHA3_BUF_SIZE_MAX/8];
-		ASSERT_ALIGNMENT(tramp, 8);
-		for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz) {
-			memcpy(tramp, data, ctx->bufsz);
-			sha3_do_chunk(ctx->state, tramp, ctx->bufsz / 8);
-		}
-	} else {
-		/* process as much ctx->bufsz-block */
-		for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz)
-			sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8);
-	}
+	/* No trampoline: load_le64 does not ask for a boundary. */
+	for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz)
+		sha3_do_chunk(ctx->state, data, ctx->bufsz / 8);
 
 
 	/* append data into buf */
@@ -232,7 +225,7 @@
 {
 	/* process full buffer if needed */
 	if (ctx->bufindex == ctx->bufsz) {
-		sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
+		sha3_do_chunk(ctx->state, ctx->buf, ctx->bufsz / 8);
 		ctx->bufindex = 0;
 	}
 
@@ -242,7 +235,7 @@
 	ctx->buf[ctx->bufsz - 1] |= 0x80;
 
 	/* process */
-	sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
+	sha3_do_chunk(ctx->state, ctx->buf, ctx->bufsz / 8);
 	ctx->bufindex = 0;
 }
 
diff --git a/cbits/crypton_sha512.c b/cbits/crypton_sha512.c
--- a/cbits/crypton_sha512.c
+++ b/cbits/crypton_sha512.c
@@ -91,13 +91,16 @@
 #define s0(x)       (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
 #define s1(x)       (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
 
-static void sha512_do_chunk_generic(struct sha512_ctx *ctx, uint64_t *buf)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static void sha512_do_chunk_generic(struct sha512_ctx *ctx, const uint8_t *buf)
 {
 	uint64_t a, b, c, d, e, f, g, h, t1, t2;
 	int i;
 	uint64_t w[80];
 
-	cpu_to_be64_array(w, buf, 16);
+	for (i = 0; i < 16; i++)
+		w[i] = load_be64(buf + 8 * i);
 
 	for (i = 16; i < 80; i++)
 		w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
@@ -135,10 +138,18 @@
  * widespread than the SHA-256 ones, so ask before using them.  Two threads
  * racing to answer here both write the same value.
  */
-extern void crypton_sha512_armv8_do_chunk(uint64_t state[8], const uint64_t buf[16]);
+extern void crypton_sha512_armv8_do_chunk(uint64_t state[8], const uint8_t buf[128]);
 extern int crypton_sha512_armv8_available(void);
 
+/* Resolved before there is a second thread; see the constructor in
+ * cbits/crypton_aes.c for why.  The test below then only ever reads. */
 static int sha512_use_armv8 = -1;
+
+__attribute__((constructor))
+static void sha512_armv8_ctor(void)
+{
+	sha512_use_armv8 = crypton_sha512_armv8_available();
+}
 #endif
 
 
@@ -154,7 +165,7 @@
                                                 const void *data, size_t blocks);
 #endif
 
-static void sha512_do_chunk(struct sha512_ctx *ctx, uint64_t *buf)
+static void sha512_do_chunk(struct sha512_ctx *ctx, const uint8_t *buf)
 {
 #ifdef SHA512_ASM
 	crypton_x86_ia32cap_resolve();
@@ -192,7 +203,7 @@
 	/* process partial buffer if there's enough data to make a block */
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		sha512_do_chunk(ctx, (uint64_t *) ctx->buf);
+		sha512_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
@@ -210,18 +221,9 @@
 		len -= (uint32_t) blocks * 128;
 	}
 #else
-	if (need_alignment(data, 8)) {
-		uint64_t tramp[16];
-		ASSERT_ALIGNMENT(tramp, 8);
-		for (; len >= 128; len -= 128, data += 128) {
-			memcpy(tramp, data, 128);
-			sha512_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 128-block as possible */
-		for (; len >= 128; len -= 128, data += 128)
-			sha512_do_chunk(ctx, (uint64_t *) data);
-	}
+	/* No trampoline: load_be64 does not ask for a boundary. */
+	for (; len >= 128; len -= 128, data += 128)
+		sha512_do_chunk(ctx, data);
 #endif
 
 	/* append data into buf */
@@ -344,7 +346,7 @@
 		/* re-init the context, otherwise len is changed */
 		memset(ctx, 0, sizeof(*ctx));
 		for (i = 0; i < 8; i++)
-			ctx->h[i] = cpu_to_be64(((uint64_t *) out)[i]);
+			ctx->h[i] = load_be64(out + 8 * i);
 		}
 	}
 }
diff --git a/cbits/crypton_skein256.c b/cbits/crypton_skein256.c
--- a/cbits/crypton_skein256.c
+++ b/cbits/crypton_skein256.c
@@ -37,7 +37,9 @@
 static const uint8_t K256_6[2] = { 58, 22, };
 static const uint8_t K256_7[2] = { 32, 32, };
 
-static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len)
+/* The four words are read out of the block rather than the block being
+ * pointed at as though it were an array of them; see crypton_md5.c. */
+static inline void skein256_do_chunk(struct skein256_ctx *ctx, const uint8_t *bufp, uint32_t len)
 {
 	uint64_t x[4];
 	uint64_t ts[3];
@@ -78,11 +80,18 @@
 	ROUND(0,3,2,1,K256_7); \
 	INJECTKEY((i*2) + 2)
 
-	x[0] = le64_to_cpu(buf[0]) + ks[0];
-	x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0];
-	x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1];
-	x[3] = le64_to_cpu(buf[3]) + ks[3];
+	uint64_t buf[4];
 
+	buf[0] = load_le64(bufp);
+	buf[1] = load_le64(bufp + 8);
+	buf[2] = load_le64(bufp + 16);
+	buf[3] = load_le64(bufp + 24);
+
+	x[0] = buf[0] + ks[0];
+	x[1] = buf[1] + ks[1] + ts[0];
+	x[2] = buf[2] + ks[2] + ts[1];
+	x[3] = buf[3] + ks[3];
+
 	/* 9 pass of 8 rounds = 72 rounds */
 	PASS(0);
 	PASS(1);
@@ -98,10 +107,10 @@
 	ctx->t0 = ts[0];
 	ctx->t1 = ts[1];
 
-	ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]);
-        ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]);
-        ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]);
-        ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);
+	ctx->h[0] = x[0] ^ buf[0];
+	ctx->h[1] = x[1] ^ buf[1];
+	ctx->h[2] = x[2] ^ buf[2];
+	ctx->h[3] = x[3] ^ buf[3];
 }
 
 void crypton_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
@@ -115,7 +124,7 @@
 	buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING);
 	buf[1] = cpu_to_le64(hashlen);
 	buf[2] = 0; /* tree info, not implemented */
-	skein256_do_chunk(ctx, buf, 4*8);
+	skein256_do_chunk(ctx, (const uint8_t *) buf, 4*8);
 
 	SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
 }
@@ -130,7 +139,7 @@
 	to_fill = 32 - ctx->bufindex;
 
 	if (ctx->bufindex == 32) {
-		skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
+		skein256_do_chunk(ctx, ctx->buf, 32);
 		ctx->bufindex = 0;
 	}
 
@@ -138,24 +147,17 @@
 	 * and there's without doubt further blocks */
 	if (ctx->bufindex && len > to_fill) {
 		memcpy(ctx->buf + ctx->bufindex, data, to_fill);
-		skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
+		skein256_do_chunk(ctx, ctx->buf, 32);
 		len -= to_fill;
 		data += to_fill;
 		ctx->bufindex = 0;
 	}
 
-	if (need_alignment(data, 8)) {
-		uint64_t tramp[4];
-		ASSERT_ALIGNMENT(tramp, 8);
-		for (; len > 32; len -= 32, data += 32) {
-			memcpy(tramp, data, 32);
-			skein256_do_chunk(ctx, tramp, 32);
-		}
-	} else {
-		/* process as much 32-block as possible except the last one in case we finalize */
-		for (; len > 32; len -= 32, data += 32)
-			skein256_do_chunk(ctx, (uint64_t *) data, 32);
-	}
+	/* No trampoline for a block that is not on an eight-byte boundary: the
+	 * words are read with load_le64 now, which does not ask.  The last
+	 * block is left for the finalisation. */
+	for (; len > 32; len -= 32, data += 32)
+		skein256_do_chunk(ctx, data, 32);
 
 	/* append data into buf */
 	if (len) {
@@ -174,7 +176,7 @@
 	/* if buf is not complete pad with 0 bytes */
 	if (ctx->bufindex < 32)
 		memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex);
-	skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);
+	skein256_do_chunk(ctx, ctx->buf, ctx->bufindex);
 
 	memset(ctx->buf, '\0', 32);
 
@@ -187,9 +189,9 @@
 	/* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */
 	for (i = 0; i*32 < outsize; i++) {
 		uint64_t w[4];
-		*((uint64_t *) ctx->buf) = cpu_to_le64(i);
+		store_le64(ctx->buf, i);
 		SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));
-		skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));
+		skein256_do_chunk(ctx, ctx->buf, sizeof(uint64_t));
 
 		n = outsize - i * 32;
 		if (n >= 32) n = 32;
diff --git a/cbits/crypton_skein256.h b/cbits/crypton_skein256.h
--- a/cbits/crypton_skein256.h
+++ b/cbits/crypton_skein256.h
@@ -37,8 +37,8 @@
 
 #define SKEIN256_CTX_SIZE		sizeof(struct skein256_ctx)
 
-void cryponite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
-void cryponite_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len);
-void cryponite_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out);
+void crypton_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
+void crypton_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len);
+void crypton_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out);
 
 #endif
diff --git a/cbits/crypton_skein512.c b/cbits/crypton_skein512.c
--- a/cbits/crypton_skein512.c
+++ b/cbits/crypton_skein512.c
@@ -37,7 +37,9 @@
 static const uint8_t K512_6[4] = { 25, 29, 39, 43, };
 static const uint8_t K512_7[4] = {  8, 35, 56, 22, };
 
-static inline void skein512_do_chunk(struct skein512_ctx *ctx, uint64_t *buf, uint32_t len)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static inline void skein512_do_chunk(struct skein512_ctx *ctx, const uint8_t *bufp, uint32_t len)
 {
 	uint64_t x[8];
 	uint64_t ts[3];
@@ -88,15 +90,21 @@
 	ROUND(6,1,0,7,2,5,4,3,K512_7); \
 	INJECTKEY((i*2) + 2)
 
-	x[0] = le64_to_cpu(buf[0]) + ks[0];
-	x[1] = le64_to_cpu(buf[1]) + ks[1];
-	x[2] = le64_to_cpu(buf[2]) + ks[2];
-	x[3] = le64_to_cpu(buf[3]) + ks[3];
-	x[4] = le64_to_cpu(buf[4]) + ks[4];
-	x[5] = le64_to_cpu(buf[5]) + ks[5] + ts[0];
-	x[6] = le64_to_cpu(buf[6]) + ks[6] + ts[1];
-	x[7] = le64_to_cpu(buf[7]) + ks[7];
+	uint64_t buf[8];
+	int bi;
 
+	for (bi = 0; bi < 8; bi++)
+		buf[bi] = load_le64(bufp + 8 * bi);
+
+	x[0] = buf[0] + ks[0];
+	x[1] = buf[1] + ks[1];
+	x[2] = buf[2] + ks[2];
+	x[3] = buf[3] + ks[3];
+	x[4] = buf[4] + ks[4];
+	x[5] = buf[5] + ks[5] + ts[0];
+	x[6] = buf[6] + ks[6] + ts[1];
+	x[7] = buf[7] + ks[7];
+
 	/* 9 pass of 8 rounds = 72 rounds */
 	PASS(0);
 	PASS(1);
@@ -112,14 +120,14 @@
 	ctx->t0 = ts[0];
 	ctx->t1 = ts[1];
 
-	ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]);
-        ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]);
-        ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]);
-        ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);
-        ctx->h[4] = x[4] ^ cpu_to_le64(buf[4]);
-        ctx->h[5] = x[5] ^ cpu_to_le64(buf[5]);
-        ctx->h[6] = x[6] ^ cpu_to_le64(buf[6]);
-        ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]);
+	ctx->h[0] = x[0] ^ buf[0];
+        ctx->h[1] = x[1] ^ buf[1];
+        ctx->h[2] = x[2] ^ buf[2];
+        ctx->h[3] = x[3] ^ buf[3];
+        ctx->h[4] = x[4] ^ buf[4];
+        ctx->h[5] = x[5] ^ buf[5];
+        ctx->h[6] = x[6] ^ buf[6];
+        ctx->h[7] = x[7] ^ buf[7];
 }
 
 void crypton_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen)
@@ -133,7 +141,7 @@
 	buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING);
 	buf[1] = cpu_to_le64(hashlen);
 	buf[2] = 0; /* tree info, not implemented */
-	skein512_do_chunk(ctx, buf, 4*8);
+	skein512_do_chunk(ctx, (const uint8_t *) buf, 4*8);
 
 	SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
 }
@@ -148,7 +156,7 @@
 	to_fill = 64 - ctx->bufindex;
 
 	if (ctx->bufindex == 64) {
-		skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64);
+		skein512_do_chunk(ctx, ctx->buf, 64);
 		ctx->bufindex = 0;
 	}
 
@@ -156,24 +164,15 @@
 	 * and there's without doubt further blocks */
 	if (ctx->bufindex && len > to_fill) {
 		memcpy(ctx->buf + ctx->bufindex, data, to_fill);
-		skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64);
+		skein512_do_chunk(ctx, ctx->buf, 64);
 		len -= to_fill;
 		data += to_fill;
 		ctx->bufindex = 0;
 	}
 
-	if (need_alignment(data, 8)) {
-		uint64_t tramp[8];
-		ASSERT_ALIGNMENT(tramp, 8);
-		for (; len > 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			skein512_do_chunk(ctx, tramp, 64);
-		}
-	} else {
-		/* process as much 64-block as possible except the last one in case we finalize */
-		for (; len > 64; len -= 64, data += 64)
-			skein512_do_chunk(ctx, (uint64_t *) data, 64);
-	}
+	/* No trampoline: load_le64 does not ask for a boundary. */
+	for (; len > 64; len -= 64, data += 64)
+		skein512_do_chunk(ctx, data, 64);
 
 	/* append data into buf */
 	if (len) {
@@ -192,7 +191,7 @@
 	/* if buf is not complete pad with 0 bytes */
 	if (ctx->bufindex < 64)
 		memset(ctx->buf + ctx->bufindex, '\0', 64 - ctx->bufindex);
-	skein512_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);
+	skein512_do_chunk(ctx, ctx->buf, ctx->bufindex);
 
 	memset(ctx->buf, '\0', 64);
 
@@ -205,9 +204,9 @@
 	/* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */
 	for (i = 0; i*64 < outsize; i++) {
 		uint64_t w[8];
-		*((uint64_t *) ctx->buf) = cpu_to_le64(i);
+		store_le64(ctx->buf, i);
 		SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));
-		skein512_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));
+		skein512_do_chunk(ctx, ctx->buf, sizeof(uint64_t));
 
 		n = outsize - i * 64;
 		if (n >= 64) n = 64;
diff --git a/cbits/crypton_skein512.h b/cbits/crypton_skein512.h
--- a/cbits/crypton_skein512.h
+++ b/cbits/crypton_skein512.h
@@ -37,8 +37,8 @@
 
 #define SKEIN512_CTX_SIZE		sizeof(struct skein512_ctx)
 
-void cryponite_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
-void cryponite_skein512_update(struct skein512_ctx *ctx, const uint8_t *data, uint32_t len);
-void cryponite_skein512_finalize(struct skein512_ctx *ctx, uint32_t hashlen, uint8_t *out);
+void crypton_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
+void crypton_skein512_update(struct skein512_ctx *ctx, const uint8_t *data, uint32_t len);
+void crypton_skein512_finalize(struct skein512_ctx *ctx, uint32_t hashlen, uint8_t *out);
 
 #endif
diff --git a/cbits/crypton_tiger.c b/cbits/crypton_tiger.c
--- a/cbits/crypton_tiger.c
+++ b/cbits/crypton_tiger.c
@@ -306,7 +306,9 @@
 	ctx->h[2] = 0xf096a5b4c3b2e187ULL;
 }
 
-static inline void tiger_do_chunk(struct tiger_ctx *ctx, uint64_t *buf)
+/* The words are read out of the block rather than the block being pointed at
+ * as though it were an array of them; see crypton_md5.c. */
+static inline void tiger_do_chunk(struct tiger_ctx *ctx, const uint8_t *buf)
 {
 	uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
 	uint64_t a,b,c;
@@ -314,8 +316,8 @@
 	b = ctx->h[1];
 	c = ctx->h[2];
 
-	x0 = cpu_to_le64(buf[0]); x1 = cpu_to_le64(buf[1]); x2 = cpu_to_le64(buf[2]); x3 = cpu_to_le64(buf[3]);
-	x4 = cpu_to_le64(buf[4]); x5 = cpu_to_le64(buf[5]); x6 = cpu_to_le64(buf[6]); x7 = cpu_to_le64(buf[7]);
+	x0 = load_le64(buf     ); x1 = load_le64(buf +  8); x2 = load_le64(buf + 16); x3 = load_le64(buf + 24);
+	x4 = load_le64(buf + 32); x5 = load_le64(buf + 40); x6 = load_le64(buf + 48); x7 = load_le64(buf + 56);
 
 #define BYTEOF(c, n) ((uint8_t) (c >> ((n * 8))))
 
@@ -376,24 +378,15 @@
 	/* process partial buffer if there's enough data to make a block */
 	if (index && len >= to_fill) {
 		memcpy(ctx->buf + index, data, to_fill);
-		tiger_do_chunk(ctx, (uint64_t *) ctx->buf);
+		tiger_do_chunk(ctx, ctx->buf);
 		len -= to_fill;
 		data += to_fill;
 		index = 0;
 	}
 
-	if (need_alignment(data, 8)) {
-		uint64_t tramp[8];
-		ASSERT_ALIGNMENT(tramp, 8);
-		for (; len >= 64; len -= 64, data += 64) {
-			memcpy(tramp, data, 64);
-			tiger_do_chunk(ctx, tramp);
-		}
-	} else {
-		/* process as much 64-block as possible */
-		for (; len >= 64; len -= 64, data += 64)
-			tiger_do_chunk(ctx, (uint64_t *) data);
-	}
+	/* No trampoline: load_le64 does not ask for a boundary. */
+	for (; len >= 64; len -= 64, data += 64)
+		tiger_do_chunk(ctx, data);
 
 	/* append data into buf */
 	if (len)
diff --git a/cbits/crypton_xsalsa.c b/cbits/crypton_xsalsa.c
--- a/cbits/crypton_xsalsa.c
+++ b/cbits/crypton_xsalsa.c
@@ -41,7 +41,7 @@
   memset(ctx, 0, sizeof(*ctx));
   ctx->nb_rounds = nb_rounds;
 
-  /* Create initial 512-bit input block:
+  /* Create initial 512-bit input crypton_salsa_block:
        (x0, x5, x10, x15) is the Salsa20 constant
        (x1, x2, x3, x4, x11, x12, x13, x14) is a 256-bit key
        (x6, x7, x8, x9) is the first 128 bits of a 192-bit nonce
@@ -56,7 +56,7 @@
 void crypton_xsalsa_derive(crypton_salsa_context *ctx,
                               uint32_t ivlen, const uint8_t *iv)
 {
-  /* Finish creating initial 512-bit input block:
+  /* Finish creating initial 512-bit input crypton_salsa_block:
        (x6, x7, x8, x9) is the first 128 bits of a 192-bit nonce
 
      Except iv has been shifted by 64 bits so there are now only 128 bits ahead.
@@ -65,15 +65,15 @@
   ctx->st.d[ 9] += load_le32(iv + 4);
 
   /* Compute (z0, z1, . . . , z15) = doubleround ^(r/2) (x0, x1, . . . , x15) */
-  block hSalsa;
-  memset(&hSalsa, 0, sizeof(block));
+  crypton_salsa_block hSalsa;
+  memset(&hSalsa, 0, sizeof(crypton_salsa_block));
   crypton_salsa_core_xor(ctx->nb_rounds, &hSalsa, &ctx->st);
  
-  /* Build a new 512-bit input block (x′0, x′1, . . . , x′15):
+  /* Build a new 512-bit input crypton_salsa_block (x′0, x′1, . . . , x′15):
        (x′0, x′5, x′10, x′15) is the Salsa20 constant
        (x′1,x′2,x′3,x′4,x′11,x′12,x′13,x′14) = (z0,z5,z10,z15,z6,z7,z8,z9)
        (x′6,x′7) is the last 64 bits of the 192-bit nonce
-       (x′8, x′9) is a 64-bit block counter.
+       (x′8, x′9) is a 64-bit crypton_salsa_block counter.
   */
   ctx->st.d[ 1] = hSalsa.d[ 0] - ctx->st.d[ 0];
   ctx->st.d[ 2] = hSalsa.d[ 5] - ctx->st.d[ 5];
diff --git a/cbits/decaf/ed448goldilocks/decaf.c b/cbits/decaf/ed448goldilocks/decaf.c
--- a/cbits/decaf/ed448goldilocks/decaf.c
+++ b/cbits/decaf/ed448goldilocks/decaf.c
@@ -1462,7 +1462,10 @@
             uint32_t pos = __builtin_ctz((uint32_t)current), odd = (uint32_t)current >> pos;
             int32_t delta = odd & mask;
             if (odd & 1<<(table_bits+1)) delta -= (1<<(table_bits+1));
-            current -= delta << pos;
+            /* delta is negative half the time and shifting a negative
+             * value left is undefined; current is unsigned, so the shift is
+             * done there and means the same thing. */
+            current -= (uint64_t)delta << pos;
             control[position].power = pos + 16*(w-1);
             control[position].addend = delta;
             position--;
diff --git a/cbits/decaf/include/word.h b/cbits/decaf/include/word.h
--- a/cbits/decaf/include/word.h
+++ b/cbits/decaf/include/word.h
@@ -68,7 +68,7 @@
  * Expand bit 0 of the given uint8_t to a mask_t all 1 or all 0
  * The input must be either 0 or 1
  */
-CRYPTON_DECAF_INLINE mask_t bit_to_mask(uint8_t bit) {
+static CRYPTON_DECAF_INLINE mask_t bit_to_mask(uint8_t bit) {
 #ifdef _MSC_VER
 #pragma warning ( push)
 #pragma warning ( disable : 4146)
diff --git a/cbits/ed25519/ed25519.c b/cbits/ed25519/ed25519.c
--- a/cbits/ed25519/ed25519.c
+++ b/cbits/ed25519/ed25519.c
@@ -12,8 +12,33 @@
 #include "ed25519-randombytes.h"
 #include "ed25519-hash.h"
 #include "ed25519-crypton-exts.h"
+#include "ed25519/ed25519_s2n.h"
 
 /*
+	The base point multiplied by a scalar, packed.  s2n-bignum's assembly
+	where it is built -- twice the speed of the table below, and signing
+	does this twice -- and ed25519-donna's own table where it is not.
+*/
+static void
+ed25519_base_pack(ed25519_public_key out, const bignum256modm s) {
+	ge25519 ALIGN(16) p;
+
+#if defined(CRYPTON_S2N_BIGNUM) && defined(__BYTE_ORDER__) \
+    && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	unsigned char e[32];
+
+	contract256_modm(e, s);
+	if (crypton_ed25519_base_mult(out, e)) {
+		memset(e, 0, sizeof e);
+		return;
+	}
+	memset(e, 0, sizeof e);
+#endif
+	ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
+	ge25519_pack(out, &p);
+}
+
+/*
 	Generates a (extsk[0..31]) and aExt (extsk[32..63])
 */
 
@@ -38,14 +63,12 @@
 void
 ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
 	bignum256modm a;
-	ge25519 ALIGN(16) A;
 	hash_512bits extsk;
 
 	/* A = aB */
 	ed25519_extsk(extsk, sk);
 	expand256_modm(a, extsk, 32);
-	ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
-	ge25519_pack(pk, &A);
+	ed25519_base_pack(pk, a);
 }
 
 
@@ -53,7 +76,6 @@
 ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
 	ed25519_hash_context ctx;
 	bignum256modm r, S, a;
-	ge25519 ALIGN(16) R;
 	hash_512bits extsk, hashr, hram;
 
 	ed25519_extsk(extsk, sk);
@@ -66,8 +88,7 @@
 	expand256_modm(r, hashr, 64);
 
 	/* R = rB */
-	ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
-	ge25519_pack(RS, &R);
+	ed25519_base_pack(RS, r);
 
 	/* S = H(R,A,m).. */
 	ed25519_hram(hram, RS, pk, m, mlen);
diff --git a/cbits/ed25519/ed25519_s2n.c b/cbits/ed25519/ed25519_s2n.c
new file mode 100644
--- /dev/null
+++ b/cbits/ed25519/ed25519_s2n.c
@@ -0,0 +1,65 @@
+/*
+ * Ed25519's base point multiplication through the vendored s2n-bignum.
+ *
+ * Signing does this twice: once for the nonce's point R, and once for the
+ * public key, which crypton derives from the secret key at every signature
+ * rather than trusting the one it is handed.  Both go through here, so both
+ * halves of a signature move at once.
+ *
+ * Measured on an Apple M4, one multiplication with the encoding:
+ * ed25519-donna 7.5 us against s2n-bignum 3.5.
+ */
+#include <string.h>
+
+#include "ed25519/ed25519_s2n.h"
+
+#if defined(CRYPTON_S2N_BIGNUM) && defined(__BYTE_ORDER__) \
+    && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define CRYPTON_ED25519_S2N 1
+#include "crypton_cpu.h"
+
+extern void edwards25519_scalarmulbase(uint64_t res[8],
+                                       const uint64_t scalar[4]);
+extern void edwards25519_scalarmulbase_alt(uint64_t res[8],
+                                           const uint64_t scalar[4]);
+extern void edwards25519_encode(uint8_t z[32], const uint64_t p[8]);
+
+/* The same question as everywhere else in cbits/s2n: a microarchitecture one
+ * on ARM that no feature bit answers, and exactly a feature bit on x86-64. */
+static int use_alt(void)
+{
+#if defined(__aarch64__) || defined(__arm64__)
+#ifdef __APPLE__
+	return 1;
+#else
+	return 0;
+#endif
+#else
+	return (crypton_x86_simd_features() & CRYPTON_X86_ADX) == 0;
+#endif
+}
+#endif
+
+int crypton_ed25519_base_mult(uint8_t out[32], const uint8_t scalar[32])
+{
+#ifdef CRYPTON_ED25519_S2N
+	/* the assembly takes four little-endian 64-bit words, which is the
+	 * same bits as the 32 little-endian bytes the scalar is kept in */
+	uint64_t s[4], p[8];
+
+	memcpy(s, scalar, 32);
+	if (use_alt())
+		edwards25519_scalarmulbase_alt(p, s);
+	else
+		edwards25519_scalarmulbase(p, s);
+	edwards25519_encode(out, p);
+
+	memset(s, 0, sizeof s);
+	memset(p, 0, sizeof p);
+	return 1;
+#else
+	(void) out;
+	(void) scalar;
+	return 0;
+#endif
+}
diff --git a/cbits/ed25519/ed25519_s2n.h b/cbits/ed25519/ed25519_s2n.h
new file mode 100644
--- /dev/null
+++ b/cbits/ed25519/ed25519_s2n.h
@@ -0,0 +1,14 @@
+#ifndef CRYPTON_ED25519_S2N_H
+#define CRYPTON_ED25519_S2N_H
+
+#include <stdint.h>
+
+/* The base point multiplied by a scalar, packed into Ed25519's 32-byte
+ * encoding.  The scalar is 32 little-endian bytes, already reduced.
+ *
+ * Returns 1 when the vendored s2n-bignum did the work and 0 when it is not
+ * built, in which case the caller multiplies the base point itself.
+ */
+int crypton_ed25519_base_mult(uint8_t out[32], const uint8_t scalar[32]);
+
+#endif
diff --git a/cbits/include32/p256/p256_gf.h b/cbits/include32/p256/p256_gf.h
--- a/cbits/include32/p256/p256_gf.h
+++ b/cbits/include32/p256/p256_gf.h
@@ -76,6 +76,13 @@
     0
 };
 static const felem kZero = {0};
+
+/* the curve's b, in Montgomery form, for the complete addition formula */
+static const felem kB = {
+    0x13897bbf, 0x9cdf622, 0x43090d8, 0x2e67c4,
+    0x176b5678, 0x2afdc84, 0xd196888, 0xb090e90,
+    0xb8600c3
+};
 static const felem kP = {
     0x1fffffff, 0xfffffff, 0x1fffffff, 0x3ff,
     0, 0, 0x200000, 0xf000000,
@@ -86,96 +93,99 @@
     0, 0, 0x400000, 0xe000000,
     0x1fffffff
 };
-/* kPrecomputed contains precomputed values to aid the calculation of scalar
- * multiples of the base point, G. It's actually two, equal length, tables
- * concatenated.
+/* kPrecomputed holds the multiples of the base point G that the comb in
+ * scalar_base_mult reads.  Two tables of sixteen affine points, one after the
+ * other.
  *
- * The first table contains (x,y) felem pairs for 16 multiples of the base
- * point, G.
+ * The comb takes five bits of the signed all-bits-set representation at a
+ * time, from positions 52 apart, and the two tables are offset from each
+ * other by 26:
  *
- *   Index  |  Index (binary) | Value
- *       0  |           0000  | 0G (all zeros, omitted)
- *       1  |           0001  | G
- *       2  |           0010  | 2**64G
- *       3  |           0011  | 2**64G + G
- *       4  |           0100  | 2**128G
- *       5  |           0101  | 2**128G + G
- *       6  |           0110  | 2**128G + 2**64G
- *       7  |           0111  | 2**128G + 2**64G + G
- *       8  |           1000  | 2**192G
- *       9  |           1001  | 2**192G + G
- *      10  |           1010  | 2**192G + 2**64G
- *      11  |           1011  | 2**192G + 2**64G + G
- *      12  |           1100  | 2**192G + 2**128G
- *      13  |           1101  | 2**192G + 2**128G + G
- *      14  |           1110  | 2**192G + 2**128G + 2**64G
- *      15  |           1111  | 2**192G + 2**128G + 2**64G + G
+ *   first table    i, 52+i, 104+i, 156+i, 208+i
+ *   second table   26+i, 78+i, 130+i, 182+i, 234+i
  *
- * The second table follows the same style, but the terms are 2**32G,
- * 2**96G, 2**160G, 2**224G.
+ * for i from 25 down to 0, which covers all 260 bits between them.
  *
+ * Every digit of that representation is +-1, so a block of five teeth takes
+ * one of thirty-two values -- and they come in pairs that differ only by
+ * sign.  So sixteen entries are enough: the top tooth is taken positive, bit
+ * j of the index says that tooth j agrees with it, and where the top tooth is
+ * negative the caller negates y, which costs a subtraction.  Entry zero is a
+ * point like any other here, unlike the unsigned table this replaces, where
+ * it stood for the infinity.
+ *
+ *   Index  |  Index (binary) | Value
+ *       0  |           0000  | 2**208G - 2**156G - 2**104G - 2**52G - G
+ *       1  |           0001  | 2**208G - 2**156G - 2**104G - 2**52G + G
+ *     ...  |            ...  | ...
+ *      15  |           1111  | 2**208G + 2**156G + 2**104G + 2**52G + G
+ *
  * This is ~2KB of data. */
-static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
-    0x11522878, 0xe730d41, 0xdb60179, 0x4afe2ff, 0x12883add, 0xcaddd88, 0x119e7edc, 0xd4a6eab, 0x3120bee,
-    0x1d2aac15, 0xf25357c, 0x19e45cdd, 0x5c721d0, 0x1992c5a5, 0xa237487, 0x154ba21, 0x14b10bb, 0xae3fe3,
-    0xd41a576, 0x922fc51, 0x234994f, 0x60b60d3, 0x164586ae, 0xce95f18, 0x1fe49073, 0x3fa36cc, 0x5ebcd2c,
-    0xb402f2f, 0x15c70bf, 0x1561925c, 0x5a26704, 0xda91e90, 0xcdc1c7f, 0x1ea12446, 0xe1ade1e, 0xec91f22,
-    0x26f7778, 0x566847e, 0xa0bec9e, 0x234f453, 0x1a31f21a, 0xd85e75c, 0x56c7109, 0xa267a00, 0xb57c050,
-    0x98fb57, 0xaa837cc, 0x60c0792, 0xcfa5e19, 0x61bab9e, 0x589e39b, 0xa324c5, 0x7d6dee7, 0x2976e4b,
-    0x1fc4124a, 0xa8c244b, 0x1ce86762, 0xcd61c7e, 0x1831c8e0, 0x75774e1, 0x1d96a5a9, 0x843a649, 0xc3ab0fa,
-    0x6e2e7d5, 0x7673a2a, 0x178b65e8, 0x4003e9b, 0x1a1f11c2, 0x7816ea, 0xf643e11, 0x58c43df, 0xf423fc2,
-    0x19633ffa, 0x891f2b2, 0x123c231c, 0x46add8c, 0x54700dd, 0x59e2b17, 0x172db40f, 0x83e277d, 0xb0dd609,
-    0xfd1da12, 0x35c6e52, 0x19ede20c, 0xd19e0c0, 0x97d0f40, 0xb015b19, 0x449e3f5, 0xe10c9e, 0x33ab581,
-    0x56a67ab, 0x577734d, 0x1dddc062, 0xc57b10d, 0x149b39d, 0x26a9e7b, 0xc35df9f, 0x48764cd, 0x76dbcca,
-    0xca4b366, 0xe9303ab, 0x1a7480e7, 0x57e9e81, 0x1e13eb50, 0xf466cf3, 0x6f16b20, 0x4ba3173, 0xc168c33,
-    0x15cb5439, 0x6a38e11, 0x73658bd, 0xb29564f, 0x3f6dc5b, 0x53b97e, 0x1322c4c0, 0x65dd7ff, 0x3a1e4f6,
-    0x14e614aa, 0x9246317, 0x1bc83aca, 0xad97eed, 0xd38ce4a, 0xf82b006, 0x341f077, 0xa6add89, 0x4894acd,
-    0x9f162d5, 0xf8410ef, 0x1b266a56, 0xd7f223, 0x3e0cb92, 0xe39b672, 0x6a2901a, 0x69a8556, 0x7e7c0,
-    0x9b7d8d3, 0x309a80, 0x1ad05f7f, 0xc2fb5dd, 0xcbfd41d, 0x9ceb638, 0x1051825c, 0xda0cf5b, 0x812e881,
-    0x6f35669, 0x6a56f2c, 0x1df8d184, 0x345820, 0x1477d477, 0x1645db1, 0xbe80c51, 0xc22be3e, 0xe35e65a,
-    0x1aeb7aa0, 0xc375315, 0xf67bc99, 0x7fdd7b9, 0x191fc1be, 0x61235d, 0x2c184e9, 0x1c5a839, 0x47a1e26,
-    0xb7cb456, 0x93e225d, 0x14f3c6ed, 0xccc1ac9, 0x17fe37f3, 0x4988989, 0x1a90c502, 0x2f32042, 0xa17769b,
-    0xafd8c7c, 0x8191c6e, 0x1dcdb237, 0x16200c0, 0x107b32a1, 0x66c08db, 0x10d06a02, 0x3fc93, 0x5620023,
-    0x16722b27, 0x68b5c59, 0x270fcfc, 0xfad0ecc, 0xe5de1c2, 0xeab466b, 0x2fc513c, 0x407f75c, 0xbaab133,
-    0x9705fe9, 0xb88b8e7, 0x734c993, 0x1e1ff8f, 0x19156970, 0xabd0f00, 0x10469ea7, 0x3293ac0, 0xcdc98aa,
-    0x1d843fd, 0xe14bfe8, 0x15be825f, 0x8b5212, 0xeb3fb67, 0x81cbd29, 0xbc62f16, 0x2b6fcc7, 0xf5a4e29,
-    0x13560b66, 0xc0b6ac2, 0x51ae690, 0xd41e271, 0xf3e9bd4, 0x1d70aab, 0x1029f72, 0x73e1c35, 0xee70fbc,
-    0xad81baf, 0x9ecc49a, 0x86c741e, 0xfe6be30, 0x176752e7, 0x23d416, 0x1f83de85, 0x27de188, 0x66f70b8,
-    0x181cd51f, 0x96b6e4c, 0x188f2335, 0xa5df759, 0x17a77eb6, 0xfeb0e73, 0x154ae914, 0x2f3ec51, 0x3826b59,
-    0xb91f17d, 0x1c72949, 0x1362bf0a, 0xe23fddf, 0xa5614b0, 0xf7d8f, 0x79061, 0x823d9d2, 0x8213f39,
-    0x1128ae0b, 0xd095d05, 0xb85c0c2, 0x1ecb2ef, 0x24ddc84, 0xe35e901, 0x18411a4a, 0xf5ddc3d, 0x3786689,
-    0x52260e8, 0x5ae3564, 0x542b10d, 0x8d93a45, 0x19952aa4, 0x996cc41, 0x1051a729, 0x4be3499, 0x52b23aa,
-    0x109f307e, 0x6f5b6bb, 0x1f84e1e7, 0x77a0cfa, 0x10c4df3f, 0x25a02ea, 0xb048035, 0xe31de66, 0xc6ecaa3,
-    0x28ea335, 0x2886024, 0x1372f020, 0xf55d35, 0x15e4684c, 0xf2a9e17, 0x1a4a7529, 0xcb7beb1, 0xb2a78a1,
-    0x1ab21f1f, 0x6361ccf, 0x6c9179d, 0xb135627, 0x1267b974, 0x4408bad, 0x1cbff658, 0xe3d6511, 0xc7d76f,
-    0x1cc7a69, 0xe7ee31b, 0x54fab4f, 0x2b914f, 0x1ad27a30, 0xcd3579e, 0xc50124c, 0x50daa90, 0xb13f72,
-    0xb06aa75, 0x70f5cc6, 0x1649e5aa, 0x84a5312, 0x329043c, 0x41c4011, 0x13d32411, 0xb04a838, 0xd760d2d,
-    0x1713b532, 0xbaa0c03, 0x84022ab, 0x6bcf5c1, 0x2f45379, 0x18ae070, 0x18c9e11e, 0x20bca9a, 0x66f496b,
-    0x3eef294, 0x67500d2, 0xd7f613c, 0x2dbbeb, 0xb741038, 0xe04133f, 0x1582968d, 0xbe985f7, 0x1acbc1a,
-    0x1a6a939f, 0x33e50f6, 0xd665ed4, 0xb4b7bd6, 0x1e5a3799, 0x6b33847, 0x17fa56ff, 0x65ef930, 0x21dc4a,
-    0x2b37659, 0x450fe17, 0xb357b65, 0xdf5efac, 0x15397bef, 0x9d35a7f, 0x112ac15f, 0x624e62e, 0xa90ae2f,
-    0x107eecd2, 0x1f69bbe, 0x77d6bce, 0x5741394, 0x13c684fc, 0x950c910, 0x725522b, 0xdc78583, 0x40eeabb,
-    0x1fde328a, 0xbd61d96, 0xd28c387, 0x9e77d89, 0x12550c40, 0x759cb7d, 0x367ef34, 0xae2a960, 0x91b8bdc,
-    0x93462a9, 0xf469ef, 0xb2e9aef, 0xd2ca771, 0x54e1f42, 0x7aaa49, 0x6316abb, 0x2413c8e, 0x5425bf9,
-    0x1bed3e3a, 0xf272274, 0x1f5e7326, 0x6416517, 0xea27072, 0x9cedea7, 0x6e7633, 0x7c91952, 0xd806dce,
-    0x8e2a7e1, 0xe421e1a, 0x418c9e1, 0x1dbc890, 0x1b395c36, 0xa1dc175, 0x1dc4ef73, 0x8956f34, 0xe4b5cf2,
-    0x1b0d3a18, 0x3194a36, 0x6c2641f, 0xe44124c, 0xa2f4eaa, 0xa8c25ba, 0xf927ed7, 0x627b614, 0x7371cca,
-    0xba16694, 0x417bc03, 0x7c0a7e3, 0x9c35c19, 0x1168a205, 0x8b6b00d, 0x10e3edc9, 0x9c19bf2, 0x5882229,
-    0x1b2b4162, 0xa5cef1a, 0x1543622b, 0x9bd433e, 0x364e04d, 0x7480792, 0x5c9b5b3, 0xe85ff25, 0x408ef57,
-    0x1814cfa4, 0x121b41b, 0xd248a0f, 0x3b05222, 0x39bb16a, 0xc75966d, 0xa038113, 0xa4a1769, 0x11fbc6c,
-    0x917e50e, 0xeec3da8, 0x169d6eac, 0x10c1699, 0xa416153, 0xf724912, 0x15cd60b7, 0x4acbad9, 0x5efc5fa,
-    0xf150ed7, 0x122b51, 0x1104b40a, 0xcb7f442, 0xfbb28ff, 0x6ac53ca, 0x196142cc, 0x7bf0fa9, 0x957651,
-    0x4e0f215, 0xed439f8, 0x3f46bd5, 0x5ace82f, 0x110916b6, 0x6db078, 0xffd7d57, 0xf2ecaac, 0xca86dec,
-    0x15d6b2da, 0x965ecc9, 0x1c92b4c2, 0x1f3811, 0x1cb080f5, 0x2d8b804, 0x19d1c12d, 0xf20bd46, 0x1951fa7,
-    0xa3656c3, 0x523a425, 0xfcd0692, 0xd44ddc8, 0x131f0f5b, 0xaf80e4a, 0xcd9fc74, 0x99bb618, 0x2db944c,
-    0xa673090, 0x1c210e1, 0x178c8d23, 0x1474383, 0x10b8743d, 0x985a55b, 0x2e74779, 0x576138, 0x9587927,
-    0x133130fa, 0xbe05516, 0x9f4d619, 0xbb62570, 0x99ec591, 0xd9468fe, 0x1d07782d, 0xfc72e0b, 0x701b298,
-    0x1863863b, 0x85954b8, 0x121a0c36, 0x9e7fedf, 0xf64b429, 0x9b9d71e, 0x14e2f5d8, 0xf858d3a, 0x942eea8,
-    0xda5b765, 0x6edafff, 0xa9d18cc, 0xc65e4ba, 0x1c747e86, 0xe4ea915, 0x1981d7a1, 0x8395659, 0x52ed4e2,
-    0x87d43b7, 0x37ab11b, 0x19d292ce, 0xf8d4692, 0x18c3053f, 0x8863e13, 0x4c146c0, 0x6bdf55a, 0x4e4457d,
-    0x16152289, 0xac78ec2, 0x1a59c5a2, 0x2028b97, 0x71c2d01, 0x295851f, 0x404747b, 0x878558d, 0x7d29aa4,
-    0x13d8341f, 0x8daefd7, 0x139c972d, 0x6b7ea75, 0xd4a9dde, 0xff163d8, 0x81d55d7, 0xa5bef68, 0xb7b30d8,
-    0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78,
+static const limb kPrecomputed[NLIMBS * 2 * 16 * 2] = {
+    0xe01bd76, 0xa0be8b3, 0x8494c1d, 0x609ab3d, 0x1188042f, 0x499c03d, 0x1df7cd26, 0x51b33c5, 0x1fb3bce,
+    0x39cdd45, 0xdc0dd9b, 0xe3053d7, 0x1ffaf46, 0x9ac284a, 0xac051d4, 0x1c09fe1b, 0x8227cbf, 0x5bf049b,
+    0xb9487d, 0x2ecb75f, 0x194825bf, 0xd70cf28, 0x14e528f3, 0x4d8670c, 0x35bbabb, 0x6b692ca, 0xd96d08,
+    0x1db081dc, 0xa87ea7b, 0x190e5549, 0xa4cf420, 0x1e151385, 0xaf3d4bd, 0x4057e9f, 0x5078feb, 0x154519a,
+    0xbf15dea, 0x453fa25, 0x1171c85a, 0x576c824, 0x154e7060, 0x71ede6e, 0x160467a2, 0xdea8a44, 0x81ffcb1,
+    0x61a56fa, 0x76119b9, 0x110bfb9b, 0x3d527ea, 0x1997bdb4, 0xe1d1253, 0x180ce91c, 0x11950ee, 0x53d5938,
+    0x694e7c9, 0xe0cf337, 0x16d8ae50, 0x202517f, 0x4d02e16, 0xd13b5fd, 0xfae97eb, 0xa1c7f60, 0x1206fe8,
+    0x11b1c908, 0xf8a82f, 0x6ab17a0, 0x48058e8, 0x2d0feb, 0xfada550, 0x658edb9, 0xa17567a, 0x8daa44d,
+    0x6361dc9, 0xec00c0e, 0x151a7b1c, 0xb35a683, 0x1643fe02, 0x70155c0, 0x1f131d45, 0x3998068, 0x25beef8,
+    0x88138de, 0x8995ce4, 0x18565c50, 0x60f12b6, 0xc47a656, 0x4a82bd9, 0xb547a17, 0xb333474, 0xe86513a,
+    0x7f8d2bc, 0x7f0f16c, 0x8cde475, 0x1ac3d5c, 0x1a832c9a, 0x6a93e7a, 0x19833281, 0xcec82db, 0x4f08cc,
+    0x72c4394, 0x4686520, 0x1e845ce, 0xfb181a1, 0xf5135a5, 0xa1265d6, 0x6c63ce8, 0xe81797e, 0x5dbcd5a,
+    0x2a5d603, 0x1ad4e91, 0xc86e1b3, 0x793abea, 0x1b8610a4, 0x8d5b975, 0x74dd850, 0xbbca81, 0xd7c35d8,
+    0x1bab7afc, 0x4df749, 0x4acb4ea, 0xfae8c89, 0x14552ae5, 0x6dc1c20, 0x14f629f, 0x2368fe5, 0xe5a9cba,
+    0x67576f7, 0x9c77c50, 0x1d63c92a, 0xbbb9ef8, 0xa7530d4, 0x963335, 0xfa09c54, 0xb6d03e3, 0xed1a022,
+    0x19c59f49, 0x45c823d, 0x17a28df1, 0x80ae516, 0xe2ada82, 0x19b97fb, 0x13a9ebf, 0xf1e7606, 0xde03632,
+    0x14e318b9, 0x7b57b83, 0x51a9a92, 0x3378a17, 0x1cde9289, 0x45956c2, 0x2bbab5e, 0x780b1f5, 0x8356034,
+    0x75eca28, 0x6f39648, 0xf2fdbda, 0x4c65cd9, 0xb3759e7, 0x710c0b1, 0xda24432, 0x8d236aa, 0xf4c449f,
+    0xaf9ba24, 0xb83ea7f, 0x1e46ecc3, 0x3f277b0, 0x6acdecd, 0x1f597d1, 0x8483d72, 0x57d29dd, 0x66d4060,
+    0x167c14af, 0xc142ded, 0xc1689ca, 0x651aa52, 0x8d05768, 0x9709cfa, 0x165fd283, 0x9f6f583, 0x9833b54,
+    0xd17e2d6, 0x2915c32, 0x1970ef24, 0xe8ca45b, 0x11c29e09, 0x8121f26, 0xb5afbe1, 0x10c80ec, 0x834a25c,
+    0xa37f0b0, 0xd6bac16, 0xed484fc, 0x8799206, 0x13db8bb1, 0xdce615c, 0x13320329, 0x79dc25, 0x914e7af,
+    0x860a414, 0xb8a9434, 0x50396ce, 0x902d3e6, 0x15c152f3, 0x3753c64, 0x970c055, 0xba296fb, 0x64bd63b,
+    0x118cbb94, 0x9d4274f, 0x121cdbfe, 0xb9137cf, 0xc8bddf1, 0xa1598d0, 0x446ab41, 0x11f1df2, 0x68115f1,
+    0x2f1f708, 0xee35192, 0x1dfeb3fc, 0x4e1e1a6, 0x1d9adcbb, 0x6688662, 0x63ad21b, 0x9d9a9e1, 0xb0f8b4b,
+    0xcd8bc3a, 0x3577d8, 0x1ffcb97d, 0xd31e8d6, 0x1c776310, 0x95b4ef7, 0x185a82ed, 0xe40bbb0, 0xbca1ea,
+    0x19462e0b, 0x2252179, 0x14f14f09, 0x565e68d, 0x7ba5f37, 0x4cd1858, 0x167941b3, 0x4d1c7a7, 0x7aef1ab,
+    0x1599efe9, 0x658e78d, 0x1ad33917, 0x7e74797, 0x19152edc, 0xdf7dc18, 0xdf677c, 0x9315d96, 0x4ba8eec,
+    0xc45cd82, 0x1acfa03, 0xe265b49, 0xcfa6eb, 0x89d7619, 0x7b05, 0x1ba11068, 0xe1672d3, 0x655622a,
+    0x1607ca6, 0x339049, 0x5454f70, 0x10edd75, 0x1133ceb7, 0xe3eec39, 0xc263156, 0xeb6ddbe, 0x10360a7,
+    0xfd5f981, 0x47dd502, 0x1e66dbbe, 0x8820b63, 0xeee91ef, 0xffde293, 0xb66325d, 0x3a5a2a, 0x6a2acbb,
+    0x11e949bc, 0xf6a6d57, 0x6b2ca24, 0xad903ec, 0x1e55de0, 0xe7074ed, 0xe681934, 0xea44010, 0xaa490cc,
+    0x512324a, 0x6a5eb00, 0xee5e100, 0xd60a02b, 0x1b89c993, 0x5cffb70, 0xa49030c, 0x405aee, 0xe1b27cc,
+    0x2e73a15, 0x9ca8dc0, 0x781dbff, 0x9fd85e0, 0x1884e4c8, 0x40873f6, 0x32d4b69, 0xf42f753, 0xeaf4c38,
+    0x2802a4c, 0x1283dac, 0x759100a, 0xcb3ba75, 0xf3203d3, 0xf89b8aa, 0x7caa59e, 0x384a60a, 0x37f69e7,
+    0x1e56d569, 0x120c552, 0x181734aa, 0x4fcd9b4, 0x7918e4e, 0xcd7938a, 0x2bbd8b2, 0x19f4f97, 0xa7af533,
+    0xbb69948, 0x3eff33e, 0x1f3ac118, 0x3739770, 0x58898fd, 0x623fafb, 0xa7e6d93, 0xd31a676, 0x615192d,
+    0xf543d28, 0xe61ce5a, 0x10ae4b39, 0xcd5a8d7, 0x1b34c6de, 0x81997ad, 0x198e2093, 0xd9b6ff7, 0x9a5954f,
+    0x16782589, 0xed3c1ab, 0x62dc4a5, 0xac12d0c, 0x8bc8b7c, 0x168ec4e, 0x177e11dc, 0x407df09, 0x4056e85,
+    0x9858305, 0xfe445e9, 0x18b1230a, 0x815ee9f, 0xa852eb4, 0x89444e0, 0x1a83481, 0x479359b, 0x2192576,
+    0x16d5e61b, 0xfe480c4, 0x1d60b8b7, 0x1c6e798, 0x1a01310, 0x9998572, 0x7c59f75, 0x49dda87, 0xe75e0b6,
+    0x1b2b7536, 0xb267d8, 0x15443085, 0x45e5924, 0x7fb947f, 0x296915d, 0x38fc56b, 0x4bae39f, 0xb218e7c,
+    0x115c3b16, 0x9d95f0c, 0xa50ac4c, 0xcce8037, 0xc3c7ba3, 0xf02773a, 0xbc2ad54, 0x26914c1, 0x19a4b8d,
+    0x3f8a1a6, 0xa0b8459, 0x1f77a521, 0x7d93297, 0x1dddb4b2, 0x9e4cd1c, 0x6e28403, 0xd7ce413, 0x5575b62,
+    0x12bb7dc1, 0xbdfb15e, 0xa542867, 0xe943d3e, 0x1367fbdd, 0x37b387, 0x14e4d75f, 0xb90b09d, 0xbf6ec28,
+    0xa5182c8, 0x1e5b34e, 0xabe4602, 0x1c13efa, 0x8d1182, 0x1c2947a, 0x1e04e0e3, 0x6caecdb, 0x40f14e8,
+    0x1b845e4a, 0xa9fb149, 0xb34f513, 0x3a0fdbb, 0xfad2335, 0x5bb9342, 0x18c5ad62, 0xc97fdc3, 0x31225c7,
+    0xb28a9ee, 0x585915, 0x1e355da1, 0x26ed08e, 0xc7d06a, 0xa65f219, 0x1fdf45cd, 0xc8323ea, 0x297b9ee,
+    0x1c031098, 0x9c39cf0, 0x1287d79f, 0x69a9e32, 0x10015650, 0x1c3dfc3, 0x12dcd848, 0x3155a59, 0xeff3212,
+    0x1a6ecdd0, 0xd26bd07, 0x18e077ab, 0x442b477, 0x46b735f, 0x495d60c, 0x1b57a6e5, 0x76a368a, 0xf53bd50,
+    0xf12c5e0, 0x80a9b4, 0x15562060, 0x4102113, 0xa144ab5, 0x5fa4e9, 0x1009f5e9, 0xe34343a, 0x26fda5a,
+    0x159e06a4, 0x5fa3aad, 0x10259b5f, 0xa69947d, 0x1190417e, 0x987da3f, 0x14e1e868, 0xdcb7e1e, 0x8890f9f,
+    0x14dece80, 0x94bbf5c, 0x18513a17, 0x4ca31ca, 0xc0a2713, 0xbc46074, 0x1536f6a5, 0x43991aa, 0xb9f8f1c,
+    0x987ba48, 0xb0829ae, 0xd29d324, 0x6339c35, 0x18ace0a4, 0x5d53b55, 0xff829f4, 0xe882ecf, 0xc05164c,
+    0x6bd6bba, 0x9dfc14f, 0x1981cab3, 0xcfebf18, 0x1ddac868, 0x94ec6d4, 0x5abd4b, 0x737fdb3, 0x18f531f,
+    0xd3c2a71, 0x337178f, 0x9f7c32e, 0xd9d7fda, 0x137d191f, 0xdd0757b, 0x14b6d65, 0x179f37a, 0x67b10e1,
+    0x1bfb2cfd, 0xfe4ca43, 0x1fee2930, 0x98c2aa0, 0x9826788, 0xeaf4ceb, 0x17a6be82, 0xc899ed1, 0x500fb01,
+    0x10918e6f, 0x36179ed, 0xbca6643, 0x2d80942, 0xf1ef61, 0xadca21c, 0xbe5b3a7, 0xadae157, 0x12daac,
+    0x1337dda8, 0x6326e5d, 0x2738e1b, 0x5cb5c54, 0x98ec8a0, 0x252647d, 0x1d5c173c, 0xbdf848d, 0x9e5217b,
+    0x1d64f447, 0xb71d1a, 0xb2c2360, 0xccb6bee, 0x1245995e, 0x94a9130, 0x5b93d91, 0x76c57ff, 0xeaa91d1,
+    0x3941881, 0xc2aafbd, 0x1c0540d0, 0x1a938f0, 0x1304b724, 0x8524e10, 0x1bef780f, 0xbc0ea48, 0xbe90dae,
+    0x1d10d5d8, 0xca979e2, 0x10db5cc4, 0x54e2493, 0x44d38f3, 0xbcb73b, 0x12dcff4, 0xd0ab219, 0xde69db2,
+    0x13594366, 0xc30e05f, 0xfc245d4, 0x8c5b52f, 0x81901c7, 0xa9d1e03, 0x11ead62e, 0xb7be89b, 0xc9c8486,
+    0x132a6fa0, 0x56af9b8, 0x41cb561, 0xf74418c, 0x141c461a, 0xbc18514, 0x1d6bbb68, 0x96d43c2, 0x7108696
 };
 
 
diff --git a/cbits/include64/p256/p256_gf.h b/cbits/include64/p256/p256_gf.h
--- a/cbits/include64/p256/p256_gf.h
+++ b/cbits/include64/p256/p256_gf.h
@@ -104,102 +104,111 @@
     2, 0xfc00000000000, 0x7ffffffffffff, 0xfff7fffffffff, 0x7ffff
 };
 static const felem kZero = {0};
+
+/* the curve's b, in Montgomery form, for the complete addition formula */
+static const felem kB = {
+    0x1bec453897bbf, 0x33e210c243627, 0x484bb5ab3c017, 0x41a32d11055fb,
+    0x2e18030ec243a
+};
 static const felem kP = {
     0x7ffffffffffff, 0x1fffffffffff, 0, 0x4000000000, 0x3fffffffc0000
 };
 static const felem k2P = {
     0x7fffffffffffe, 0x3fffffffffff, 0, 0x8000000000, 0x7fffffff80000
 };
-/* kPrecomputed contains precomputed values to aid the calculation of scalar
- * multiples of the base point, G. It's actually two, equal length, tables
- * concatenated.
+/* kPrecomputed holds the multiples of the base point G that the comb in
+ * scalar_base_mult reads.  Two tables of sixteen affine points, one after the
+ * other.
  *
- * The first table contains (x,y) felem pairs for 16 multiples of the base
- * point, G.
+ * The comb takes five bits of the signed all-bits-set representation at a
+ * time, from positions 52 apart, and the two tables are offset from each
+ * other by 26:
  *
- *   Index  |  Index (binary) | Value
- *       0  |           0000  | 0G (all zeros, omitted)
- *       1  |           0001  | G
- *       2  |           0010  | 2**64G
- *       3  |           0011  | 2**64G + G
- *       4  |           0100  | 2**128G
- *       5  |           0101  | 2**128G + G
- *       6  |           0110  | 2**128G + 2**64G
- *       7  |           0111  | 2**128G + 2**64G + G
- *       8  |           1000  | 2**192G
- *       9  |           1001  | 2**192G + G
- *      10  |           1010  | 2**192G + 2**64G
- *      11  |           1011  | 2**192G + 2**64G + G
- *      12  |           1100  | 2**192G + 2**128G
- *      13  |           1101  | 2**192G + 2**128G + G
- *      14  |           1110  | 2**192G + 2**128G + 2**64G
- *      15  |           1111  | 2**192G + 2**128G + 2**64G + G
+ *   first table    i, 52+i, 104+i, 156+i, 208+i
+ *   second table   26+i, 78+i, 130+i, 182+i, 234+i
  *
- * The second table follows the same style, but the terms are 2**32G,
- * 2**96G, 2**160G, 2**224G.
+ * for i from 25 down to 0, which covers all 260 bits between them.
  *
+ * Every digit of that representation is +-1, so a block of five teeth takes
+ * one of thirty-two values -- and they come in pairs that differ only by
+ * sign.  So sixteen entries are enough: the top tooth is taken positive, bit
+ * j of the index says that tooth j agrees with it, and where the top tooth is
+ * negative the caller negates y, which costs a subtraction.  Entry zero is a
+ * point like any other here, unlike the unsigned table this replaces, where
+ * it stood for the infinity.
+ *
+ *   Index  |  Index (binary) | Value
+ *       0  |           0000  | 2**208G - 2**156G - 2**104G - 2**52G - G
+ *       1  |           0001  | 2**208G - 2**156G - 2**104G - 2**52G + G
+ *     ...  |            ...  | ...
+ *      15  |           1111  | 2**208G + 2**156G + 2**104G + 2**52G + G
+ *
  * This is ~2KB of data. */
-static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
-    0x661a831522878, 0xf17fb6d805e79, 0x5889441d6ea57, 0xae33cfdb995bb, 0xc482fbb529ba,
-    0x4a6af9d2aac15, 0x90e867917377c, 0x487cc962d2ae3, 0xec2a97443446e, 0x2b8ff8c52c42,
-    0x45f8a2d41a576, 0xb06988d2653e4, 0x718b22c357305, 0x33fc920e79d2b, 0x17af34b0fe8db,
-    0x38e17eb402f2f, 0x3382558649705, 0x47f6d48f482d1, 0x7bd42488d9b83, 0x3b247c8b86b78,
-    0x4d08fc26f7778, 0x7a29a82fb2795, 0x75cd18f90d11a, 0xad8e213b0bc, 0x2d5f0142899e8,
-    0x506f98098fb57, 0x2f0c98301e4aa, 0x39b30dd5cf67d, 0x9c146498ab13c, 0xa5db92df5b7b,
-    0x184897fc4124a, 0xe3f73a19d8aa, 0x4e1c18e47066b, 0x27b2d4b52eaee, 0x30eac3ea10e99,
-    0x4e74546e2e7d5, 0x1f4dde2d97a1d, 0x6ead0f88e1200, 0x7dec87c220f02, 0x3d08ff096310f,
-    0x23e5659633ffa, 0x6ec648f08c722, 0x3172a3806ea35, 0xf6e5b681eb3c5, 0x2c3758260f89d,
-    0x38dca4fd1da12, 0xf06067b78830d, 0x3194be87a068c, 0x78893c7eb602b, 0xcead60438432,
-    0x6ee69a56a67ab, 0xd886f77701895, 0x67b0a4d9cee2b, 0x3586bbf3e4d53, 0x1db6f32921d93,
-    0x260756ca4b366, 0x4f40e9d2039fa, 0x4f3f09f5a82bf, 0xccde2d641e8cd, 0x305a30cd2e8c5,
-    0x471c235cb5439, 0xab279cd962f5a, 0x17e1fb6e2dd94, 0xfe64589800a77, 0xe8793d99775f,
-    0x48c62f4e614aa, 0xbf76ef20eb2a4, 0x669c672556c, 0x24683e0eff056, 0x12252b369ab76,
-    0x821de9f162d5, 0xf911ec99a95be, 0x6721f065c906b, 0x58d452035c736, 0x1f9f01a6a15,
-    0x6135009b7d8d3, 0xdaeeeb417dfc0, 0x63865fea0ee17, 0x6e0a304b939d6, 0x204ba2076833d,
-    0x4ade586f35669, 0x2c1077e34611a, 0x5b1a3bea3b81a, 0xf97d018a22c8b, 0x38d7996b08af8,
-    0x6ea62baeb7aa0, 0xebdcbd9ef2670, 0x35dc8fe0df3fe, 0xe458309d20c24, 0x11e87898716a0,
-    0x7c44bab7cb456, 0xd64d3cf1bb64, 0x189bff1bf9e66, 0xb5218a049311, 0x285dda6cbcc81,
-    0x3238dcafd8c7c, 0x607736c8de0, 0xdb83d99508b1, 0x4e1a0d404cd81, 0x1588008c00ff2,
-    0x16b8b36722b27, 0x876609c3f3f1a, 0x66b72ef0e17d6, 0x705f8a279d568, 0x2eaac4cd01fdd,
-    0x1171ce9705fe9, 0xffc79cd3264ee, 0x700c8ab4b80f0, 0x208d3d4f57a1, 0x337262a8ca4eb,
-    0x297fd01d843fd, 0xa90956fa097f8, 0x529759fdb3845, 0x1d78c5e2d0397, 0x3d6938a4adbf3,
-    0x16d5853560b66, 0xf138946b9a430, 0x2ab79f4dea6a0, 0xd42053ee43ae1, 0x3b9c3ef1cf870,
-    0x598934ad81baf, 0x5f1821b1d07a7, 0x416bb3a973ff3, 0x23f07bd0a047a, 0x19bdc2e09f786,
-    0x56dc9981cd51f, 0xfbace23c8cd65, 0x673bd3bf5b52e, 0x46a95d229fd61, 0xe09ad64bcfb1,
-    0xe5292b91f17d, 0xfeefcd8afc287, 0x58f52b0a58711, 0x4800f20c201ef, 0x2084fce608f67,
-    0x12ba0b128ae0b, 0x5977ae17030b4, 0x101126ee420f6, 0xf70823495c6bd, 0xde19a27d7770,
-    0x5c6ac852260e8, 0x9d22950ac4356, 0x441cca955246c, 0x660a34e5332d9, 0x14ac8ea92f8d2,
-    0x6b6d7709f307e, 0x67d7e13879db, 0x2ea8626f9fbbd, 0x99609006a4b40, 0x31bb2a8f8c779,
-    0x10c04828ea335, 0xae9acdcbc080a, 0x617af2342607a, 0xc7494ea53e553, 0x2ca9e2872defa,
-    0x6c399fab21f1f, 0xab139b245e758, 0x3ad933dcba589, 0x4797fecb08811, 0x31f5dbf8f594,
-    0x7dc6361cc7a69, 0xc8a7953ead3f9, 0x79ed693d18015, 0x418a024999a6a, 0x2c4fdc9436aa,
-    0x1eb98cb06aa75, 0x2989592796a9c, 0x11194821e425, 0xe27a648228388, 0x35d834b6c12a0,
-    0x541807713b532, 0x7ae0a1008aaee, 0x7017a29bcb5e, 0x6b193c23c315c, 0x19bd25ac82f2a,
-    0x6a01a43eef294, 0xddf5b5fd84f19, 0x33f5ba081c016, 0xdeb052d1bc082, 0x6b2f06afa617,
-    0x7ca1eda6a939f, 0xbdeb35997b50c, 0x47f2d1bccda5, 0xc2ff4adfed667, 0x87712997be4,
-    0x21fc2e2b37659, 0xf7d62cd5ed951, 0x27fa9cbdf7efa, 0xba25582bf3a6b, 0x2a42b8bd89398,
-    0x6d377d07eecd2, 0x9ca1df5af387, 0x1109e3427e2ba, 0xce4aa4572a19, 0x103baaef71e16,
-    0x2c3b2dfde328a, 0xbec4b4a30e1ef, 0x37d92a86204f3, 0x806cfde68eb39, 0x246e2f72b8aa5,
-    0x68d3de93462a9, 0x53b8acba6bbc3, 0x2492a70fa1696, 0x38c62d5760f55, 0x15096fe4904f2,
-    0x4e44e9bed3e3a, 0xb28bfd79cc9bc, 0x6a77513839320, 0x480dcec6739db, 0x3601b739f2465,
-    0x43c348e2a7e1, 0xe448106327879, 0x175d9cae1b0ed, 0xd3b89dee743b8, 0x392d73ca255bc,
-    0x32946db0d3a18, 0x9261b09907cc, 0x5ba517a755722, 0x51f24fdaf5184, 0x1cdc732989ed8,
-    0x2f7806ba16694, 0xae0c9f029f8d0, 0xd8b45102ce1, 0xca1c7db9316d6, 0x162088a67066f,
-    0x39de35b2b4162, 0xa19f550d88ae9, 0x7921b27026cde, 0x94b936b66e900, 0x1023bd5fa17fc,
-    0x436837814cfa4, 0x29113492283c4, 0x66d1cdd8b51d8, 0xa540702278eb2, 0x47ef1b29285d,
-    0x587b50917e50e, 0xb4cda75bab3b, 0x112520b0a9886, 0x66b9ac16fee49, 0x17bf17e92b2eb,
-    0x2456a2f150ed7, 0xfa214412d0280, 0x3ca7dd947fe5b, 0xa72c28598d58a, 0x255d945efc3e,
-    0x2873f04e0f215, 0x74178fd1af57b, 0x788848b5b2d6, 0xb1ffafaae0db6, 0x32a1b7b3cbb2a,
-    0x4bd9935d6b2da, 0x9c08f24ad30a5, 0x4e58407a80f, 0x1b3a3825a5b17, 0x6547e9fc82f5,
-    0x47484aa3656c3, 0x6ee43f341a494, 0x64a98f87adea2, 0x619b3f8e95f01, 0xb6e513266ed8,
-    0x421c2a673090, 0xa1c1de32348c7, 0x55b85c3a1e8a3, 0xe05ce8ef330b4, 0x2561e49c15d84,
-    0x40aa2d33130fa, 0x12b827d35866f, 0xfe4cf62c8ddb, 0x2fa0ef05bb28d, 0x1c06ca63f1cb8,
-    0x32a971863863b, 0xff6fc86830da1, 0x71e7b25a14cf3, 0xea9c5ebb1373a, 0x250bbaa3e1634,
-    0x5b5ffeda5b765, 0xf25d2a746331b, 0x115e3a3f43632, 0x67303af43c9d5, 0x14bb538a0e559,
-    0x75623687d43b7, 0xa349674a4b38d, 0x613c61829ffc6, 0x689828d8110c7, 0x139115f5af7d5,
-    0xf1d856152289, 0x45cbe967168ab, 0x51f38e1680901, 0x34808e8f652b0, 0x1f4a6a921e156,
-    0x35dfaf3d8341f, 0xf53ace725cb63, 0x3d86a54eef35b, 0xa103aabaffe2c, 0x2decc36296fbd,
-    0x510282be73d6f, 0xd4e6365db206a, 0x4bdc5f5bb8bf3, 0xde7ea32a3aee7, 0x71269e274305,
+static const limb kPrecomputed[NLIMBS * 2 * 16 * 2] = {
+    0x17d166e01bd76, 0xd59ea12530768, 0x3d8c40217b04, 0x17bef9a4c9338, 0x7ecef3946ccf,
+    0x1bb3639cdd45, 0xd7a338c14f5f7, 0x1d44d614250ff, 0xff813fc37580a, 0x16fc126e089f2,
+    0x596ebe0b9487d, 0x6794652096fcb, 0x70ca729479eb8, 0x286b775769b0c, 0x365b421ada4b,
+    0xfd4f7db081dc, 0x7a1064395526a, 0x4bdf0a89c2d26, 0xac80afd3f5e7a, 0x551466941e3f,
+    0x27f44abf15dea, 0x641245c721691, 0x66eaa738302bb, 0x12c08cf44e3db, 0x207ff2c77aa29,
+    0x42337261a56fa, 0x93f5442fee6dd, 0x253ccbdeda1ea, 0xbb019d239c3a2, 0x14f564e046543,
+    0x19e66e694e7c9, 0x28bfdb62b9438, 0x5fd268170b101, 0x81f5d2fd7a276, 0x481bfa2871fd,
+    0x71505f1b1c908, 0x2c741aac5e803, 0x55001687f5a40, 0xe8cb1db73f5b4, 0x236a913685d59,
+    0x181c6361dc9, 0xd341d469ec73b, 0x5c0b21ff0159a, 0xa3e263a8ae02a, 0x96fbbe0e6601,
+    0x32b9c888138de, 0x895b615971422, 0x3d9623d32b307, 0xd16a8f42e9505, 0x3a1944eacccd1,
+    0x61e2d87f8d2bc, 0x1eae233791d5f, 0x67ad41964d0d6, 0x6f3066502d527, 0x13c23333b20b,
+    0x50ca4072c4394, 0xc0d087a117391, 0x5d67a89ad2fd8, 0xf8d8c79d1424c, 0x176f356ba05e5,
+    0x5a9d222a5d603, 0xd5f5321b86cc6, 0x175dc308523c9, 0x4e9bb0a11ab7, 0x35f0d7602ef2a,
+    0x1bee93bab7afc, 0x464492b2d3a81, 0x420a2a9572fd7, 0x9429ec53edb83, 0x396a72e88da3f,
+    0xef8a067576f7, 0xcf7c758f24aa7, 0x33553a986a5dd, 0x8df4138a812c6, 0x3b46808adb40f,
+    0x39047b9c59f49, 0x728b5e8a37c51, 0x7fb7156d41405, 0x182753d7e3372, 0x3780d8cbc79d8,
+    0x6af7074e318b9, 0xc50b946a6a49e, 0x6c2e6f494499b, 0xd457756bc8b2a, 0x20d580d1e02c7,
+    0x672c9075eca28, 0x2e6cbcbf6f69b, 0xb159bacf3a63, 0xa9b448864e218, 0x3d31127e348da,
+    0x7d4feaf9ba24, 0x3bd8791bb30ee, 0x7d13566f669f9, 0x750907ae43eb2, 0x19b501815f4a7,
+    0x285bdb67c14af, 0xd529305a272b0, 0x4fa4682bb4328, 0xecbfa5072e13, 0x260ced527dbd6,
+    0x22b864d17e2d6, 0x522de5c3bc90a, 0x7268e14f04f46, 0xb16b5f7c30243, 0x20d2897043203,
+    0x57582ca37f0b0, 0xc9033b5213f35, 0x15c9edc5d8c3c, 0x966640653b9cc, 0x24539ebc1e770,
+    0x152868860a414, 0x69f3140e5b3ae, 0x464ae0a979c81, 0xed2e180aa6ea7, 0x192f58eee8a5b,
+    0x284e9f18cbb94, 0x9be7c8736ffa7, 0xd0645eef8dc8, 0xc888d568342b3, 0x1a0457c447c77,
+    0x46a3242f1f708, 0xf0d377facff3b, 0x662ecd6e5da70, 0x84c75a436cd10, 0x2c3e2d2e766a7,
+    0x6aefb0cd8bc3a, 0xf46b7ff2e5f40, 0x6f7e3bb188698, 0xc30b505db2b69, 0x2f287ab902ee,
+    0x4a42f39462e0b, 0xf346d3c53c248, 0x583dd2f9bab2, 0x9ecf2836699a3, 0x1ebbc6ad3471e,
+    0x31cf1b599efe9, 0xa3cbeb4ce45d9, 0x418c8a976e3f3, 0x581becef9befb, 0x12ea3bb24c576,
+    0x59f406c45cd82, 0xd375b8996d246, 0x30544ebb0c867, 0x4f74220d0000f, 0x195588ab859cb,
+    0x6720921607ca6, 0x6eba95153dc00, 0x439899e75b887, 0xf984c62adc7dd, 0x40d829fadb76,
+    0x7baa04fd5f981, 0x5b1f99b6ef91, 0x29377748f7c41, 0xa96cc64bbffbc, 0x1a8ab2ec0e968,
+    0x54daaf1e949bc, 0x81f61acb2893d, 0x4ed0f2aef056c, 0x41cd03269ce0e, 0x2a924333a9100,
+    0x4bd600512324a, 0x5015bb978401a, 0x370dc4e4c9eb0, 0xb94920618b9ff, 0x386c9f301016b,
+    0x151b802e73a15, 0xc2f01e076ffe7, 0x3f6c4272644fe, 0x4c65a96d2810e, 0x3abd30e3d0bdd,
+    0x507b582802a4c, 0xdd3a9d6440284, 0xaa79901e9e59, 0x28f954b3df137, 0xdfda79ce1298,
+    0x418aa5e56d569, 0x6cda605cd2a84, 0x38a3c8c72727e, 0x5c577b1659af2, 0x29ebd4cc67d3e,
+    0x5fe67cbb69948, 0xcbb87ceb0460f, 0x2fb2c44c7e9b9, 0xd94fcdb26c47f, 0x185464b74c699,
+    0x439cb4f543d28, 0xd46bc2b92ce79, 0x7add9a636f66a, 0xdf31c41270332, 0x2696553f66dbf,
+    0x2783576782589, 0x968618b71297b, 0x44e45e45be560, 0x26efc23b82d1d, 0x1015ba1501f7c,
+    0x488bd29858305, 0xf74fe2c48c2bf, 0x4e0542975a40a, 0x6c35069031288, 0x86495d91e4d6,
+    0x4901896d5e61b, 0x73cc7582e2dff, 0x5720d009880e3, 0x1cf8b3eeb3330, 0x39d782d92776a,
+    0x64cfb1b2b7536, 0x2c925510c2142, 0x15d3fdca3fa2f, 0x7c71f8ad652d2, 0x2c8639f12eb8e,
+    0x32be1915c3b16, 0x401ba942b1327, 0x73a61e3dd1e67, 0x57855aa9e04e, 0x6692e349a453,
+    0x1708b23f8a1a6, 0x994bfdde94868, 0x51ceeeda593ec, 0x4cdc508073c99, 0x155d6d8b5f390,
+    0x3f62bd2bb7dc1, 0x1e9f2950a19ef, 0x3879b3fdeef4a, 0x769c9aebe06f6, 0x2fdbb0a2e42c2,
+    0x4b669ca5182c8, 0x9f7d2af918087, 0x47a04688c10e0, 0x6fc09c1c63852, 0x103c53a1b2bb3,
+    0x3f6293b845e4a, 0x7eddacd3d44ea, 0x3427d6919a9d0, 0xf18b5ac4b772, 0xc48971f25ff7,
+    0x30b22ab28a9ee, 0x684778d576841, 0x219063e835137, 0xabfbe8b9b4cbe, 0xa5ee7bb20c8f,
+    0x739e1c031098, 0x4f194a1f5e7e7, 0x7c3800ab2834d, 0x665b9b090387b, 0x3bfcc848c5569,
+    0x4d7a0fa6ecdd0, 0x5a3be381deaf4, 0x60c235b9afa21, 0x2b6af4dca92ba, 0x3d4ef541da8da,
+    0x15368f12c5e0, 0x1089d55881802, 0x4e950a255aa08, 0xea013ebd20bf4, 0x9bf696b8d0d0,
+    0x74755b59e06a4, 0xca3ec0966d7d7, 0x23f8c820bf534, 0x7a9c3d0d130fb, 0x22243e7f72df8,
+    0x177eb94dece80, 0x18e56144e85e5, 0x746051389a65, 0xaaa6ded4b788c, 0x2e7e3c710e646,
+    0x10535c987ba48, 0xce1ab4a74c92c, 0x355c567052319, 0x3dff053e8baa7, 0x30145933a20bb,
+    0x3f829e6bd6bba, 0x5f8c66072ace7, 0x6d4eed643467f, 0xcc0b57a9729d8, 0x63d4c7dcdff6,
+    0x6e2f1ed3c2a71, 0xbfed27df0cb8c, 0x57b9be8c8fece, 0xe8296dacbba0e, 0x19ec43845e7cd,
+    0x499487bfb2cfd, 0x15507fb8a4c3f, 0x4eb4c133c44c6, 0x46f4d7d05d5e9, 0x1403ec072267b,
+    0x42f3db0918e6f, 0x4a12f29990cd, 0x21c078f7b096c, 0x5d7cb674f5b94, 0x4b6ab2b6b85,
+    0x64dcbb337dda8, 0xae2a09ce386d8, 0x47d4c764502e5, 0x37ab82e784a4c, 0x279485eef7e12,
+    0x6e3a35d64f447, 0xb5f72cb08d802, 0x130922ccaf665, 0xfcb727b232952, 0x3aaa4745db15f,
+    0x555f7a3941881, 0x9c78701503430, 0x6109825b920d4, 0x237def01f0a49, 0x2fa436baf03a9,
+    0x52f3c5d10d5d8, 0x1249c36d73132, 0x73b2269c79aa7, 0x6425b9fe81796, 0x379a76cb42ac8,
+    0x61c0bf3594366, 0xda97bf0917530, 0x60340c80e3c62, 0x6e3d5ac5d53a3, 0x3272121adefa2,
+    0x55f37132a6fa0, 0x20c61072d5855, 0x514a0e230d7ba, 0xbad776d17830, 0x1c421a5a5b50f
 };
 
 
diff --git a/cbits/p256/gen_base_table.py b/cbits/p256/gen_base_table.py
--- a/cbits/p256/gen_base_table.py
+++ b/cbits/p256/gen_base_table.py
@@ -1,7 +1,8 @@
 #!/usr/bin/env python3
-"""Build the table s2n-bignum's p256_scalarmulbase reads.
+"""Build the two tables of multiples of the base point that crypton reads.
 
-    ./gen_base_table.py 5 p256_base_table.c
+    ./gen_base_table.py 5 p256_base_table.c        # for p256_scalarmulbase
+    ./gen_base_table.py odd 7 p256_wnaf_table.c    # for p256_verify.c
 
 Its own words for the layout: for each i, j with blocksize*i <= 256 and
 1 <= j <= B, where B = 2^(blocksize-1), the multiple 2^(blocksize*i) * j * P
@@ -72,6 +73,33 @@
             base = add(base, base)
     return blocks, Bn, out
 
+def odd_table(width):
+    """The odd multiples 1P, 3P, ..., (2^(width-1)-1)P, which is what the
+    windowed form in cbits/p256/p256_verify.c reads for the base point."""
+    n = 1 << (width - 2)
+    twice = add((GX, GY), (GX, GY))
+    out, acc = [], (GX, GY)
+    for _ in range(n):
+        out.append(acc)
+        acc = add(acc, twice)
+    return out
+
+def emit_odd(width, path):
+    pts = odd_table(width)
+    with open(path, 'w') as fh:
+        fh.write("/* Generated by cbits/p256/gen_base_table.py; do not hand-edit.\n"
+                 " * The odd multiples of the base point, in Montgomery-affine\n"
+                 " * form, which cbits/p256/p256_verify.c reads.  A verification\n"
+                 " * is public, so this table is walked in variable time. */\n")
+        fh.write("#include <stdint.h>\n\n")
+        fh.write(f"const uint64_t crypton_p256_wnaf_width = {width};\n\n")
+        fh.write(f"const uint64_t crypton_p256_wnaf_table[{len(pts)*8}] = {{\n")
+        for (x, y) in pts:
+            ws = words(mont(x)) + words(mont(y))
+            fh.write("\t" + ",".join(f"0x{w:016x}ULL" for w in ws) + ",\n")
+        fh.write("};\n")
+    return len(pts), len(pts) * 64
+
 def emit(blocksize, path):
     blocks, Bn, pts = table(blocksize)
     with open(path, 'w') as fh:
@@ -88,6 +116,11 @@
     return blocks, Bn, len(pts)*64
 
 if __name__ == "__main__":
-    b = int(sys.argv[1]); path = sys.argv[2]
-    blocks, Bn, size = emit(b, path)
-    print(f"blocksize {b}: {blocks} blocks x {Bn} = {size} bytes")
+    if sys.argv[1] == "odd":
+        w = int(sys.argv[2]); path = sys.argv[3]
+        n, size = emit_odd(w, path)
+        print(f"width {w}: {n} odd multiples = {size} bytes")
+    else:
+        b = int(sys.argv[1]); path = sys.argv[2]
+        blocks, Bn, size = emit(b, path)
+        print(f"blocksize {b}: {blocks} blocks x {Bn} = {size} bytes")
diff --git a/cbits/p256/p256.c b/cbits/p256/p256.c
--- a/cbits/p256/p256.c
+++ b/cbits/p256/p256.c
@@ -223,7 +223,11 @@
   n %= P256_BITSPERDIGIT;
   for (i = P256_NDIGITS - 1; i > 0; --i) {
     crypton_p256_digit accu = (P256_DIGIT(a, i) << n);
-    accu |= (P256_DIGIT(a, i - 1) >> (P256_BITSPERDIGIT - n));
+    /* n is zero as often as it is anything else, and a digit shifted by its
+     * own width is undefined: x86 takes the count modulo the width and hands
+     * back the whole digit, ARM hands back nothing.  Two shifts that are each
+     * inside the width say the intended nothing on both. */
+    accu |= (P256_DIGIT(a, i - 1) >> (P256_BITSPERDIGIT - 1 - n) >> 1);
     P256_DIGIT(b, i) = accu;
   }
   P256_DIGIT(b, i) = (P256_DIGIT(a, i) << n);
@@ -239,7 +243,8 @@
   n %= P256_BITSPERDIGIT;
   for (i = 0; i < P256_NDIGITS - 1; ++i) {
     crypton_p256_digit accu = (P256_DIGIT(a, i) >> n);
-    accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - n));
+    /* the same full-width shift as in crypton_p256_shl above */
+    accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - 1 - n) << 1);
     P256_DIGIT(b, i) = accu;
   }
   P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> n);
@@ -253,8 +258,11 @@
     accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - 1));
     P256_DIGIT(b, i) = accu;
   }
+  /* The shift is unsigned: highbit is a carry, zero or one, and one shifted
+   * into the sign bit of the signed digit is an overflow the standard leaves
+   * undefined.  The value put into b is the same either way. */
   P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> 1) |
-      (((crypton_p256_sdigit) highbit) << (P256_BITSPERDIGIT - 1));
+      (((crypton_p256_digit) highbit) << (P256_BITSPERDIGIT - 1));
 }
 
 // Return -1, 0, 1 for a < b, a == b or a > b respectively.
diff --git a/cbits/p256/p256_ec.c b/cbits/p256/p256_ec.c
--- a/cbits/p256/p256_ec.c
+++ b/cbits/p256/p256_ec.c
@@ -33,9 +33,11 @@
 // See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
 
 #include "p256/p256_gf.h"
+#include "crypton_bzero.h"
 
 #ifdef CRYPTON_S2N_BIGNUM
 #include "p256/p256_s2n.h"
+#include "p256/p256_verify.h"
 /* the memcpy below is the two representations being the same thing */
 #if P256_BITSPERDIGIT != 64 || P256_NDIGITS != 4
 #error "CRYPTON_S2N_BIGNUM wants the 64-bit crypton_p256_int"
@@ -332,7 +334,8 @@
 }
 
 /* select_affine_point sets {out_x,out_y} to the index'th entry of table.
- * On entry: index < 16, table[0] must be zero. */
+ * On entry: index < 16.  Every entry is a point of its own -- the signed
+ * representation has no zero digit -- so the scan starts at zero. */
 static void select_affine_point(felem out_x, felem out_y, const limb* table,
                                 limb index) {
   limb i, j;
@@ -340,7 +343,7 @@
   memset(out_x, 0, sizeof(felem));
   memset(out_y, 0, sizeof(felem));
 
-  for (i = 1; i < 16; i++) {
+  for (i = 0; i < 16; i++) {
     limb mask = i ^ index;
     mask |= mask >> 2;
     mask |= mask >> 1;
@@ -355,62 +358,306 @@
   }
 }
 
+/* words_are_zero returns 1 when |v| is zero and 0 otherwise, without a
+ * branch. */
+static u32 words_are_zero(u32 v) {
+  v |= v >> 16;
+  v |= v >> 8;
+  v |= v >> 4;
+  v |= v >> 2;
+  v |= v >> 1;
+  return (v & 1) ^ 1;
+}
+
+/* The comb: five teeth to a block, the teeth of a block 52 apart and the two
+ * blocks 26 from each other, so 26 steps cover all 260 bits between them.
+ *
+ *   first block    i, 52+i, 104+i, 156+i, 208+i
+ *   second block   26+i, 78+i, 130+i, 182+i, 234+i
+ *
+ * Five teeth would want a table of 32, but the signed representation makes
+ * every digit +-1, so the thirty-two values come in pairs that differ by sign
+ * and sixteen entries serve: kPrecomputed holds the ones whose top tooth is
+ * positive and the other sign is a negated y.  That is the whole of the gain
+ * over the four-tooth unsigned comb this replaces, which took 32 steps for
+ * the same 256 bits: 25 doublings and 52 mixed additions against 31 and 64.
+ */
+#define COMB_TEETH 5
+#define COMB_STEPS 26
+#define COMB_SPAN (2 * COMB_STEPS) /* 52, the distance between a block's teeth */
+#define COMB_WORDS 9               /* 260 bits of signs, with room to add into */
+#define COMB_BIT(t, q) (((t)[(q) >> 5] >> ((q) & 31)) & 1)
+
+/* comb_recode writes into |out| the value whose bits are the signs of the
+ * scalar's all-bits-set representation: digit j is +1 where bit j of |out| is
+ * set and -1 where it is not.
+ *
+ * For an odd k below 2^260 there is exactly one such representation, and it
+ * is (k + 2^260 - 1) / 2 read as bits -- an addition and a shift, and that is
+ * all the recoding is.  An even scalar has the order added to make it odd,
+ * which changes the scalar and not the point it selects.
+ *
+ * Constant time in the scalar: every branch below is on a loop counter. */
+static void comb_recode(u32 out[COMB_WORDS],
+                        const crypton_p256_int* scalar) {
+  u32 k[COMB_WORDS], ord[COMB_WORDS];
+  u64 carry;
+  int i;
+
+  for (i = 0; i < COMB_WORDS; i++) {
+    k[i] = 0;
+    ord[i] = 0;
+  }
+  for (i = 0; i < 256; i += 32) {
+    k[i >> 5] = (u32)(P256_DIGIT(scalar, i / P256_BITSPERDIGIT)
+                      >> (i % P256_BITSPERDIGIT));
+    ord[i >> 5] = (u32)(P256_DIGIT(&crypton_SECP256r1_n, i / P256_BITSPERDIGIT)
+                        >> (i % P256_BITSPERDIGIT));
+  }
+
+  /* an even scalar becomes odd by taking on the order */
+  {
+    u32 addmask = (u32)0 - (u32)((k[0] & 1) ^ 1);
+
+    carry = 0;
+    for (i = 0; i < COMB_WORDS; i++) {
+      u64 v = (u64)k[i] + (u64)(ord[i] & addmask) + carry;
+      k[i] = (u32)v;
+      carry = v >> 32;
+    }
+  }
+
+  /* out = (k + 2^260 - 1) >> 1 */
+  carry = 0;
+  for (i = 0; i < COMB_WORDS; i++) {
+    u64 v = (u64)k[i] + (u64)(i < 8 ? 0xffffffffu : 0xfu) + carry;
+    out[i] = (u32)v;
+    carry = v >> 32;
+  }
+  for (i = 0; i < COMB_WORDS - 1; i++) {
+    out[i] = (out[i] >> 1) | (out[i + 1] << 31);
+  }
+  out[COMB_WORDS - 1] >>= 1;
+
+}
+
+/* point_add_complete_mixed sets {x3,y3,z3} = {x1,y1,z1} + {x2,y2}, where the
+ * accumulator is in projective coordinates and the added point is affine.
+ *
+ * This is Renes-Costello-Batina algorithm 5, for a curve with a = -3.  It is
+ * complete: it is right when the two points are the same, when either is the
+ * point at infinity, and when they are each other's negation, which is what
+ * point_add_mixed cannot say.  It costs 11 multiplications and two by b,
+ * against point_add_mixed's 8 multiplications and 3 squarings.
+ *
+ * The table this comb reads is affine, and an affine point has Z = 1, so
+ * Z = Z^2 = Z^3 and the same three numbers are the point in projective
+ * coordinates and in Jacobian ones.  That is what lets a comb built on
+ * Jacobian arithmetic step into this formula for one addition and back out.
+ */
+static void point_add_complete_mixed(felem x3, felem y3, felem z3,
+                                     const felem x1, const felem y1,
+                                     const felem z1, const felem x2,
+                                     const felem y2) {
+  felem t0, t1, t2, t3, t4, xx, yy, zz;
+
+  felem_mul(t0, x1, x2);
+  felem_mul(t1, y1, y2);
+  felem_sum(t3, x2, y2);
+  felem_sum(t4, x1, y1);
+  felem_mul(t3, t3, t4);
+  felem_sum(t4, t0, t1);
+  felem_diff(t3, t3, t4);
+  felem_mul(t4, y2, z1);
+  felem_sum(t4, t4, y1);
+  felem_mul(yy, x2, z1);
+  felem_sum(yy, yy, x1);
+  felem_mul(zz, kB, z1);
+  felem_diff(xx, yy, zz);
+  felem_sum(zz, xx, xx);
+  felem_sum(xx, xx, zz);
+  felem_diff(zz, t1, xx);
+  felem_sum(xx, t1, xx);
+  felem_mul(yy, kB, yy);
+  felem_sum(t1, z1, z1);
+  felem_sum(t2, t1, z1);
+  felem_diff(yy, yy, t2);
+  felem_diff(yy, yy, t0);
+  felem_sum(t1, yy, yy);
+  felem_sum(yy, t1, yy);
+  felem_sum(t1, t0, t0);
+  felem_sum(t0, t1, t0);
+  felem_diff(t0, t0, t2);
+  felem_mul(t1, t4, yy);
+  felem_mul(t2, t0, yy);
+  felem_mul(yy, xx, zz);
+  felem_sum(y3, yy, t2);
+  felem_mul(xx, t3, xx);
+  felem_diff(x3, xx, t1);
+  felem_mul(zz, t4, zz);
+  felem_mul(t1, t3, t0);
+  felem_sum(z3, zz, t1);
+}
+
+/* point_add_complete sets {x3,y3,z3} = {x1,y1,z1} + {x2,y2,z2}, both in
+ * projective coordinates.
+ *
+ * Renes-Costello-Batina algorithm 4, for a = -3, and complete for the same
+ * reasons as the mixed one above.  It costs 12 multiplications and two by b,
+ * against point_add's 11 multiplications and 5 squarings.
+ */
+static void point_add_complete(felem x3, felem y3, felem z3, const felem x1,
+                               const felem y1, const felem z1, const felem x2,
+                               const felem y2, const felem z2) {
+  felem t0, t1, t2, t3, t4, xx, yy, zz;
+
+  felem_mul(t0, x1, x2);
+  felem_mul(t1, y1, y2);
+  felem_mul(t2, z1, z2);
+  felem_sum(t3, x1, y1);
+  felem_sum(t4, x2, y2);
+  felem_mul(t3, t3, t4);
+  felem_sum(t4, t0, t1);
+  felem_diff(t3, t3, t4);
+  felem_sum(t4, y1, z1);
+  felem_sum(xx, y2, z2);
+  felem_mul(t4, t4, xx);
+  felem_sum(xx, t1, t2);
+  felem_diff(t4, t4, xx);
+  felem_sum(xx, x1, z1);
+  felem_sum(yy, x2, z2);
+  felem_mul(xx, xx, yy);
+  felem_sum(yy, t0, t2);
+  felem_diff(yy, xx, yy);
+  felem_mul(zz, kB, t2);
+  felem_diff(xx, yy, zz);
+  felem_sum(zz, xx, xx);
+  felem_sum(xx, xx, zz);
+  felem_diff(zz, t1, xx);
+  felem_sum(xx, t1, xx);
+  felem_mul(yy, kB, yy);
+  felem_sum(t1, t2, t2);
+  felem_sum(t2, t1, t2);
+  felem_diff(yy, yy, t2);
+  felem_diff(yy, yy, t0);
+  felem_sum(t1, yy, yy);
+  felem_sum(yy, t1, yy);
+  felem_sum(t1, t0, t0);
+  felem_sum(t0, t1, t0);
+  felem_diff(t0, t0, t2);
+  felem_mul(t1, t4, yy);
+  felem_mul(t2, t0, yy);
+  felem_mul(yy, xx, zz);
+  felem_sum(y3, yy, t2);
+  felem_mul(xx, t3, xx);
+  felem_diff(x3, xx, t1);
+  felem_mul(zz, t4, zz);
+  felem_mul(t1, t3, t0);
+  felem_sum(z3, zz, t1);
+}
+
+/* jacobian_to_projective sets {x2,y2,z2} to the projective form of the
+ * Jacobian point {x1,y1,z1}: (X/Z^2, Y/Z^3) is (XZ : Y : Z^3). */
+static void jacobian_to_projective(felem x2, felem y2, felem z2,
+                                   const felem x1, const felem y1,
+                                   const felem z1) {
+  felem zz, zzz;
+
+  felem_square(zz, z1);
+  felem_mul(zzz, zz, z1);
+  felem_mul(x2, x1, z1);
+  memcpy(y2, y1, sizeof(felem));
+  memcpy(z2, zzz, sizeof(felem));
+}
+
+/* projective_to_jacobian is the other way: (X/Z) is (XZ : YZ^2 : Z). */
+static void projective_to_jacobian(felem x2, felem y2, felem z2,
+                                   const felem x1, const felem y1,
+                                   const felem z1) {
+  felem zz;
+
+  felem_square(zz, z1);
+  felem_mul(x2, x1, z1);
+  felem_mul(y2, y1, zz);
+  memcpy(z2, z1, sizeof(felem));
+}
+
 /* scalar_base_mult sets {nx,ny,nz} = scalar*G where scalar is a little-endian
  * number. Note that the value of scalar must be less than the order of the
  * group. */
 static void scalar_base_mult(felem nx, felem ny, felem nz,
                              const crypton_p256_int* scalar) {
-  int i, j;
-  limb n_is_infinity_mask = -1, p_is_noninfinite_mask, mask;
-  u32 table_offset;
+  u32 rec[COMB_WORDS];
+  limb n_is_infinity_mask = -1, mask;
+  felem px, py, negy, tx, ty, tz, jx, jy, jz, cx, cy, cz;
+  int i, blk, j;
 
-  felem px, py;
-  felem tx, ty, tz;
+  comb_recode(rec, scalar);
 
   memset(nx, 0, sizeof(felem));
   memset(ny, 0, sizeof(felem));
   memset(nz, 0, sizeof(felem));
 
-  /* The loop adds bits at positions 0, 64, 128 and 192, followed by
-   * positions 32,96,160 and 224 and does this 32 times. */
-  for (i = 0; i < 32; i++) {
-    if (i) {
+  for (i = COMB_STEPS - 1; i >= 0; i--) {
+    if (i != COMB_STEPS - 1) {
       point_double(nx, ny, nz, nx, ny, nz);
     }
-    table_offset = 0;
-    for (j = 0; j <= 32; j += 32) {
-      char bit0 = crypton_p256_get_bit(scalar, 31 - i + j);
-      char bit1 = crypton_p256_get_bit(scalar, 95 - i + j);
-      char bit2 = crypton_p256_get_bit(scalar, 159 - i + j);
-      char bit3 = crypton_p256_get_bit(scalar, 223 - i + j);
-      limb index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3);
 
-      select_affine_point(px, py, kPrecomputed + table_offset, index);
-      table_offset += 30 * NLIMBS;
+    for (blk = 0; blk < 2; blk++) {
+      u32 base = (u32)(blk * COMB_STEPS + i);
+      u32 top = COMB_BIT(rec, base + (COMB_TEETH - 1) * COMB_SPAN);
+      limb index = 0;
 
-      /* Since scalar is less than the order of the group, we know that
-       * {nx,ny,nz} != {px,py,1}, unless both are zero, which we handle
-       * below. */
-      point_add_mixed(tx, ty, tz, nx, ny, nz, px, py);
-      /* The result of point_add_mixed is incorrect if {nx,ny,nz} is zero
-       * (a.k.a.  the point at infinity). We handle that situation by
-       * copying the point from the table. */
+      for (j = 0; j < COMB_TEETH - 1; j++) {
+        /* a tooth agreeing with the top one is a set bit of the index */
+        index |= (limb)(COMB_BIT(rec, base + (u32)j * COMB_SPAN) ^ top ^ 1)
+                 << j;
+      }
+
+      select_affine_point(px, py, kPrecomputed + blk * 16 * 2 * NLIMBS, index);
+      felem_diff(negy, kZero, py);
+      copy_conditional(py, negy, (limb)0 - (limb)(top ^ 1));
+
+      /* The last addition is the one that can be a point added to itself:
+       * entering it the accumulator is (k' - B)*G and what it adds is B*G,
+       * where B is the second block's digit at step zero, so the two meet
+       * when k' = 2B modulo the order.  One scalar below the order does
+       * that, and point_add_mixed cannot answer it.
+       *
+       * So that one addition goes through the complete formula instead.
+       * The table is affine, so the point just selected is the same three
+       * numbers read as projective coordinates as read as Jacobian ones --
+       * which is what lets a comb built on Jacobian arithmetic step into
+       * the formula for an addition and back out of it.  The accumulator
+       * is not affine and is converted.
+       *
+       * Measured on an M4, thread CPU time, the whole base point
+       * multiplication is 17.34 us this way against 17.30 us with an extra
+       * doubling and a mask, which is inside the spread of either. */
+      if (i == 0 && blk == 1) {
+        jacobian_to_projective(jx, jy, jz, nx, ny, nz);
+        point_add_complete_mixed(cx, cy, cz, jx, jy, jz, px, py);
+        projective_to_jacobian(tx, ty, tz, cx, cy, cz);
+      } else {
+        point_add_mixed(tx, ty, tz, nx, ny, nz, px, py);
+      }
+
+      /* The accumulator is the infinity until the first of these, and
+       * point_add_mixed cannot start from it; the point itself is the sum. */
       copy_conditional(nx, px, n_is_infinity_mask);
       copy_conditional(ny, py, n_is_infinity_mask);
       copy_conditional(nz, kOne, n_is_infinity_mask);
-
-      /* Equally, the result is also wrong if the point from the table is
-       * zero, which happens when the index is zero. We handle that by
-       * only copying from {tx,ty,tz} to {nx,ny,nz} if index != 0. */
-      p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
-      mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
+      mask = ~n_is_infinity_mask;
       copy_conditional(nx, tx, mask);
       copy_conditional(ny, ty, mask);
       copy_conditional(nz, tz, mask);
-      /* If p was not zero, then n is now non-zero. */
-      n_is_infinity_mask &= ~p_is_noninfinite_mask;
+      n_is_infinity_mask = 0;
     }
   }
+
+  /* The recoded scalar is the private key in another representation, so it
+   * does not stay on the stack. */
+  crypton_bzero(rec, sizeof(rec));
 }
 
 /* point_to_affine converts a Jacobian point to an affine point. If the input
@@ -531,16 +778,6 @@
   u8 digit[SABS_DIGITS];
 } sabs_scalar;
 
-/* words_are_zero returns 1 when |v| is zero and 0 otherwise, without a
- * branch. */
-static u32 words_are_zero(u32 v) {
-  v |= v >> 16;
-  v |= v >> 8;
-  v |= v >> 4;
-  v |= v >> 2;
-  v |= v >> 1;
-  return (v & 1) ^ 1;
-}
 
 /* sabs_recode writes the signed representation of |scalar| into |out|.
  *
@@ -551,21 +788,10 @@
  * scalar is replaced by one and the caller is told, since zero times a point
  * is the infinity this code deliberately cannot represent.
  *
- * *dbl_mask is set to all ones when the last addition of the main loop would
- * be an addition of a point to itself, which the formulas there cannot do.
- * That happens exactly when the recoded scalar k' is congruent to twice its
- * lowest digit: the accumulator entering that step is (k' - d0)*P and what it
- * adds is d0*P, so they coincide when k' - d0 = d0.  With k' below 2^257 and
- * |2*d0| at most 62, k' - 2*d0 is then either zero or the order itself, which
- * is what is tested for below.  No earlier step can do this: entering step i
- * the accumulator is 32*m*P with |32*m| below the order, and the digit is at
- * most 31 in absolute value, so the two can only coincide as integers, which
- * they cannot -- m is odd and so is never zero.
- *
  * Constant time in the scalar: every branch below is on a loop counter. */
-static limb sabs_recode(sabs_scalar* out, limb* dbl_mask,
+static limb sabs_recode(sabs_scalar* out,
                         const crypton_p256_int* scalar) {
-  u32 k[9], n[9], ksaved[9];
+  u32 k[9], n[9];
   u32 nonzero;
   limb is_zero_mask;
   int i, b;
@@ -606,10 +832,6 @@
     }
   }
 
-  for (i = 0; i < 9; i++) {
-    ksaved[i] = k[i];
-  }
-
   for (i = 0; i < SABS_DIGITS - 1; i++) {
     u32 r6 = k[0] & 63;            /* odd, so never 32 */
     u32 hi = (r6 >> 5) & 1;        /* 1 when the digit is positive */
@@ -621,27 +843,6 @@
 
     out->digit[i] = (u8)(((wabs - 1) >> 1) | ((hi ^ 1) << 4));
 
-    if (i == 0) {
-      /* k' - 2*d0, against zero and against the order. */
-      u32 two_w = (u32)(2u * r6) - 64u;   /* 2*d0, two's complement */
-      u32 two_w_ext = 0u - (hi ^ 1);      /* its sign extension */
-      u32 zero_acc = 0, order_acc = 0;
-      u64 borrow = 0;
-      int w2;
-      for (w2 = 0; w2 < 9; w2++) {
-        u32 sub = (w2 == 0) ? two_w : two_w_ext;
-        u64 d = (u64)ksaved[w2] - ((u64)sub + borrow);
-        u32 dw = (u32)d;
-        borrow = (d >> 32) & 1;
-        zero_acc |= dw;
-        order_acc |= dw ^ n[w2];
-      }
-      zero_acc |= (u32)borrow;      /* a negative difference is neither */
-      order_acc |= (u32)borrow;
-      *dbl_mask = (limb)0 - (limb)(words_are_zero(zero_acc)
-                                   | words_are_zero(order_acc));
-    }
-
     /* k -= digit, i.e. k += -digit, sign extended over the nine words. */
     for (w = 0; w < 9; w++) {
       u64 t = (u64)k[w] + (u64)(w == 0 ? mlo : ext) + carry;
@@ -687,12 +888,12 @@
                         const felem y, const crypton_p256_int* scalar) {
   /* odd[k] is (2k+1)*P, for k in 0..15. */
   felem odd[16][3];
-  felem dx, dy, dz, px, py, pz, negy, ddx, ddy, ddz;
+  felem dx, dy, dz, px, py, pz, negy, ddx, ddy, ddz, qx, qy, qz, cx, cy, cz;
   sabs_scalar rec;
-  limb is_zero_mask, dbl_mask;
+  limb is_zero_mask;
   int i, k;
 
-  is_zero_mask = sabs_recode(&rec, &dbl_mask, scalar);
+  is_zero_mask = sabs_recode(&rec, scalar);
 
   felem_assign(odd[0][0], x);
   felem_assign(odd[0][1], y);
@@ -725,19 +926,26 @@
     felem_diff(negy, kZero, py);
     copy_conditional(py, negy, SABS_NEGMASK(rec.digit[i]));
 
-    /* point_add finishes with z before it touches x, and with each of x
-     * and y before the next, so the accumulator can be its own output. */
-    point_add(nx, ny, nz, nx, ny, nz, px, py, pz);
-
     /* On the last step alone the accumulator can be the very point being
-     * added, and these formulas answer the infinity where the truth is twice
-     * that point.  Doubling it is the answer there; the recoder said whether
-     * this is that case.  One doubling on one of fifty-one iterations. */
+     * added -- the accumulator is (k' - d0)*P and it adds d0*P, so the two
+     * meet when k' = 2*d0 modulo the order, which the scalar 30 does with a
+     * digit of 15 -- and point_add answers the infinity where the truth is
+     * twice that point.  That one addition goes through the complete formula
+     * instead, with both points converted to projective coordinates and the
+     * answer converted back.  One of fifty-one iterations pays for it, and
+     * it comes to a field multiplication less than the doubling and the mask
+     * it replaces.
+     *
+     * point_add finishes with z before it touches x, and with each of x and
+     * y before the next, so on every other step the accumulator can be its
+     * own output. */
     if (i == 0) {
-      point_double(ddx, ddy, ddz, px, py, pz);
-      copy_conditional(nx, ddx, dbl_mask);
-      copy_conditional(ny, ddy, dbl_mask);
-      copy_conditional(nz, ddz, dbl_mask);
+      jacobian_to_projective(ddx, ddy, ddz, nx, ny, nz);
+      jacobian_to_projective(qx, qy, qz, px, py, pz);
+      point_add_complete(cx, cy, cz, ddx, ddy, ddz, qx, qy, qz);
+      projective_to_jacobian(nx, ny, nz, cx, cy, cz);
+    } else {
+      point_add(nx, ny, nz, nx, ny, nz, px, py, pz);
     }
   }
 
@@ -751,15 +959,8 @@
   }
 
   /* The recoded scalar is the private key in another representation, so it
-   * does not stay on the stack.  Written through a volatile pointer, since a
-   * plain memset here is dead and may be dropped. */
-  {
-    volatile unsigned char* p = (volatile unsigned char*)&rec;
-    unsigned b;
-    for (b = 0; b < sizeof(rec); b++) {
-      p[b] = 0;
-    }
-  }
+   * does not stay on the stack. */
+  crypton_bzero(&rec, sizeof(rec));
 }
 
 /* crypton_p256_base_point_mul sets {out_x,out_y} = nG, where n is < the
@@ -827,6 +1028,31 @@
   }
 
 #ifdef CRYPTON_S2N_BIGNUM
+  {
+    /* Both scalars at once, in variable time, which is what the two
+     * multiplications below are not: they are constant time, and pay for it,
+     * over values that are all public here.  It gives up on the one case the
+     * assembly's addition does not cover -- adding a point to itself -- and
+     * then the constant-time pair answers instead. */
+    uint64_t jr[3 * P256_NDIGITS];
+
+    if (crypton_p256_verify_mul(jr, P256_DIGITS(n1), P256_DIGITS(n2),
+                                P256_DIGITS(in_x), P256_DIGITS(in_y))) {
+      crypton_p256_int t;
+
+      memcpy(P256_DIGITS(&t), jr, P256_NBYTES);
+      to_montgomery(x1, &t);
+      memcpy(P256_DIGITS(&t), jr + P256_NDIGITS, P256_NBYTES);
+      to_montgomery(y1, &t);
+      memcpy(P256_DIGITS(&t), jr + 2 * P256_NDIGITS, P256_NBYTES);
+      to_montgomery(z1, &t);
+
+      point_to_affine(px, py, x1, y1, z1);
+      from_montgomery(out_x, px);
+      from_montgomery(out_y, py);
+      return;
+    }
+  }
   {
     uint64_t r1[8], r2[8], pt[2 * P256_NDIGITS];
 
diff --git a/cbits/p256/p256_verify.c b/cbits/p256/p256_verify.c
new file mode 100644
--- /dev/null
+++ b/cbits/p256/p256_verify.c
@@ -0,0 +1,300 @@
+/*
+ * The double scalar multiplication ECDSA verification does, in variable
+ * time.
+ *
+ * Verification asks for u1*G + u2*Q, and crypton used to work that out as
+ * two separate constant-time multiplications and an addition.  Nothing here
+ * is secret -- the message, the signature and the public key are all sent in
+ * the clear -- so the constant-time work is paid for nothing, and the two
+ * multiplications can share their doublings besides.  Measured, those two
+ * were 84% of a verification.
+ *
+ * So this is the usual interleaved windowed form: both scalars in
+ * width-5 non-adjacent form, a table of odd multiples of each point, and one
+ * pass down the digits with a doubling at every step and an addition where a
+ * digit is not zero.  It is s2n-bignum's Jacobian point arithmetic
+ * underneath, the same assembly the constant-time paths use.
+ *
+ * s2n-bignum's p256_montjadd is correct except when its two arguments are
+ * the same point -- that is the side condition its proof carries -- so every
+ * sum is checked for the sign of that, which is a zero z where neither
+ * argument had one.  There the answer is given up on and the caller falls
+ * back to the constant-time pair, which has no such condition.  With random
+ * inputs it does not happen; it is here because an attacker chooses the
+ * public key and the signature.
+ */
+#include <string.h>
+
+#include "p256/p256.h"
+
+#ifdef CRYPTON_S2N_BIGNUM
+
+#include "crypton_cpu.h"
+#include "p256/p256_verify.h"
+
+/* a Jacobian triple in the Montgomery domain, as the assembly keeps them */
+#define JAC 12
+#define AFF 8
+
+extern void p256_montjadd(uint64_t p3[JAC], const uint64_t p1[JAC],
+                          const uint64_t p2[JAC]);
+extern void p256_montjadd_alt(uint64_t p3[JAC], const uint64_t p1[JAC],
+                              const uint64_t p2[JAC]);
+extern void p256_montjdouble(uint64_t p3[JAC], const uint64_t p1[JAC]);
+extern void p256_montjdouble_alt(uint64_t p3[JAC], const uint64_t p1[JAC]);
+extern void p256_montjmixadd(uint64_t p3[JAC], const uint64_t p1[JAC],
+                             const uint64_t p2[AFF]);
+extern void p256_montjmixadd_alt(uint64_t p3[JAC], const uint64_t p1[JAC],
+                                 const uint64_t p2[AFF]);
+
+/* the odd multiples of the base point, from cbits/p256/gen_base_table.py */
+extern const uint64_t crypton_p256_wnaf_width;
+extern const uint64_t crypton_p256_wnaf_table[];
+extern void bignum_tomont_p256(uint64_t z[4], const uint64_t x[4]);
+extern void bignum_demont_p256(uint64_t z[4], const uint64_t x[4]);
+extern void bignum_neg_p256(uint64_t z[4], const uint64_t x[4]);
+#if !defined(__aarch64__) && !defined(__arm64__)
+extern void bignum_tomont_p256_alt(uint64_t z[4], const uint64_t x[4]);
+extern void bignum_demont_p256_alt(uint64_t z[4], const uint64_t x[4]);
+#endif
+
+/* The same question as everywhere else in cbits/s2n: a microarchitecture one
+ * on ARM that no feature bit answers, and exactly a feature bit on x86-64. */
+static int use_alt(void)
+{
+#if defined(__aarch64__) || defined(__arm64__)
+#ifdef __APPLE__
+	return 1;
+#else
+	return 0;
+#endif
+#else
+	return (crypton_x86_simd_features() & CRYPTON_X86_ADX) == 0;
+#endif
+}
+
+static void padd(uint64_t r[JAC], const uint64_t a[JAC], const uint64_t b[JAC],
+                 int alt)
+{
+	if (alt)
+		p256_montjadd_alt(r, a, b);
+	else
+		p256_montjadd(r, a, b);
+}
+
+static void pmixadd(uint64_t r[JAC], const uint64_t a[JAC],
+                    const uint64_t b[AFF], int alt)
+{
+	if (alt)
+		p256_montjmixadd_alt(r, a, b);
+	else
+		p256_montjmixadd(r, a, b);
+}
+
+static void pdouble(uint64_t r[JAC], const uint64_t a[JAC], int alt)
+{
+	if (alt)
+		p256_montjdouble_alt(r, a);
+	else
+		p256_montjdouble(r, a);
+}
+
+static void tomont(uint64_t z[4], const uint64_t x[4])
+{
+#if defined(__aarch64__) || defined(__arm64__)
+	bignum_tomont_p256(z, x);
+#else
+	if (use_alt())
+		bignum_tomont_p256_alt(z, x);
+	else
+		bignum_tomont_p256(z, x);
+#endif
+}
+
+static void demont(uint64_t z[4], const uint64_t x[4])
+{
+#if defined(__aarch64__) || defined(__arm64__)
+	bignum_demont_p256(z, x);
+#else
+	if (use_alt())
+		bignum_demont_p256_alt(z, x);
+	else
+		bignum_demont_p256(z, x);
+#endif
+}
+
+static int is_infinity(const uint64_t p[JAC])
+{
+	return (p[8] | p[9] | p[10] | p[11]) == 0;
+}
+
+/*
+ * The base point's table is a constant, so its window is as wide as the
+ * table is worth carrying: seven bits, thirty-two odd multiples, two
+ * kilobytes, and one addition every eight digits.  The public key's table
+ * has to be built for each verification, so five bits is the trade there --
+ * eight entries, seven point operations to build, and one addition every
+ * six digits.
+ */
+#define WG 7
+#define TG (1 << (WG - 2))
+#define WQ 5
+#define TQ (1 << (WQ - 2))
+#define NAF_MAX 258
+
+/*
+ * The width-W non-adjacent form of a scalar, one signed digit per bit
+ * position: odd or zero, and never two non-zero digits within W of each
+ * other.  Returns how many digits were written.
+ *
+ * The scalar is public, so the loop may look at it.
+ */
+static int wnaf(int8_t out[NAF_MAX], const uint64_t in[4], int w)
+{
+	uint64_t k[5];
+	int len = 0;
+
+	memcpy(k, in, 32);
+	k[4] = 0;
+
+	while (k[0] | k[1] | k[2] | k[3] | k[4]) {
+		int d = 0;
+
+		if (k[0] & 1) {
+			d = (int) (k[0] & ((1u << w) - 1));
+			if (d >= (1 << (w - 1)))
+				d -= 1 << w;
+			if (d > 0) {
+				uint64_t borrow = (uint64_t) d;
+				int i;
+
+				for (i = 0; i < 5 && borrow; i++) {
+					uint64_t t = k[i];
+
+					k[i] = t - borrow;
+					borrow = (k[i] > t);
+				}
+			} else {
+				uint64_t carry = (uint64_t) (-d);
+				int i;
+
+				for (i = 0; i < 5 && carry; i++) {
+					k[i] += carry;
+					carry = (k[i] < carry);
+				}
+			}
+		}
+		out[len++] = (int8_t) d;
+
+		{ /* k >>= 1 */
+			int i;
+
+			for (i = 0; i < 4; i++)
+				k[i] = (k[i] >> 1) | (k[i + 1] << 63);
+			k[4] >>= 1;
+		}
+	}
+	return len;
+}
+
+/* P, 3P, 5P, ..., (2*TQ-1)P from a Jacobian P */
+static int build_table(uint64_t t[TQ][JAC], const uint64_t p[JAC], int alt)
+{
+	uint64_t twice[JAC];
+	int i;
+
+	memcpy(t[0], p, sizeof(uint64_t) * JAC);
+	pdouble(twice, p, alt);
+	for (i = 1; i < TQ; i++) {
+		padd(t[i], t[i - 1], twice, alt);
+		/* the table is built from a point and its double, which are
+		 * never the same point unless the point has order two, and
+		 * P-256 has none */
+		if (is_infinity(t[i]) && !is_infinity(t[i - 1])
+		    && !is_infinity(twice))
+			return 0;
+	}
+	return 1;
+}
+
+/* the table entry for a digit, negated when the digit is */
+static void pick(uint64_t out[JAC], const uint64_t t[TQ][JAC], int digit)
+{
+	int idx = (digit > 0 ? digit : -digit) / 2;
+
+	memcpy(out, t[idx], sizeof(uint64_t) * JAC);
+	if (digit < 0)
+		bignum_neg_p256(out + 4, out + 4);
+}
+
+/* the same from the base point's affine table */
+static void pick_affine(uint64_t out[AFF], int digit)
+{
+	int idx = (digit > 0 ? digit : -digit) / 2;
+
+	memcpy(out, crypton_p256_wnaf_table + (size_t) idx * AFF,
+	       sizeof(uint64_t) * AFF);
+	if (digit < 0)
+		bignum_neg_p256(out + 4, out + 4);
+}
+
+int crypton_p256_verify_mul(uint64_t out[JAC], const uint64_t n1[4],
+                            const uint64_t n2[4], const uint64_t qx[4],
+                            const uint64_t qy[4])
+{
+	/* the Montgomery form of one, which is the z of an affine point */
+	static const uint64_t mont_one[4] = {
+		0x0000000000000001ULL, 0xffffffff00000000ULL,
+		0xffffffffffffffffULL, 0x00000000fffffffeULL
+	};
+	uint64_t tq[TQ][JAC];
+	uint64_t q[JAC], acc[JAC], addend[JAC], aff[AFF], sum[JAC];
+	int8_t naf1[NAF_MAX], naf2[NAF_MAX];
+	int len1, len2, len, i;
+	/* asked once rather than at every point operation */
+	const int alt = use_alt();
+
+	/* the generated table has to be the width this file walks it at */
+	if (crypton_p256_wnaf_width != WG)
+		return 0;
+
+	tomont(q, qx);
+	tomont(q + 4, qy);
+	memcpy(q + 8, mont_one, sizeof mont_one);
+
+	if (!build_table(tq, q, alt))
+		return 0;
+
+	len1 = wnaf(naf1, n1, WG);
+	len2 = wnaf(naf2, n2, WQ);
+	len = len1 > len2 ? len1 : len2;
+
+	memset(acc, 0, sizeof acc);
+	for (i = len - 1; i >= 0; i--) {
+		pdouble(acc, acc, alt);
+
+		if (i < len1 && naf1[i] != 0) {
+			/* the base point's entries are affine, which is a
+			 * cheaper addition and no table to build */
+			pick_affine(aff, naf1[i]);
+			pmixadd(sum, acc, aff, alt);
+			if (is_infinity(sum) && !is_infinity(acc))
+				return 0;
+			memcpy(acc, sum, sizeof acc);
+		}
+		if (i < len2 && naf2[i] != 0) {
+			pick(addend, tq, naf2[i]);
+			padd(sum, acc, addend, alt);
+			if (is_infinity(sum) && !is_infinity(acc))
+				return 0;
+			memcpy(acc, sum, sizeof acc);
+		}
+	}
+
+	demont(out, acc);
+	demont(out + 4, acc + 4);
+	demont(out + 8, acc + 8);
+	return 1;
+}
+
+#endif
diff --git a/cbits/p256/p256_wnaf_table.c b/cbits/p256/p256_wnaf_table.c
new file mode 100644
--- /dev/null
+++ b/cbits/p256/p256_wnaf_table.c
@@ -0,0 +1,42 @@
+/* Generated by cbits/p256/gen_base_table.py; do not hand-edit.
+ * The odd multiples of the base point, in Montgomery-affine
+ * form, which cbits/p256/p256_verify.c reads.  A verification
+ * is public, so this table is walked in variable time. */
+#include <stdint.h>
+
+const uint64_t crypton_p256_wnaf_width = 7;
+
+const uint64_t crypton_p256_wnaf_table[256] = {
+	0x79e730d418a9143cULL,0x75ba95fc5fedb601ULL,0x79fb732b77622510ULL,0x18905f76a53755c6ULL,0xddf25357ce95560aULL,0x8b4ab8e4ba19e45cULL,0xd2e88688dd21f325ULL,0x8571ff1825885d85ULL,
+	0xffac3f904eebc127ULL,0xb027f84a087d81fbULL,0x66ad77dd87cbbc98ULL,0x26936a3fb6ff747eULL,0xb04c5c1fc983a7ebULL,0x583e47ad0861fe1aULL,0x788208311a2ee98eULL,0xd5f06a29e587cc07ULL,
+	0xbe1b8aaec45c61f5ULL,0x90ec649a94b9537dULL,0x941cb5aad076c20cULL,0xc9079605890523c8ULL,0xeb309b4ae7ba4f10ULL,0x73c568efe5eb882bULL,0x3540a9877e7a1f68ULL,0x73a076bb2dd1e916ULL,
+	0x0746354ea0173b4fULL,0x2bd20213d23c00f7ULL,0xf43eaab50c23bb08ULL,0x13ba5119c3123e03ULL,0x2847d0303f5b9d4dULL,0x6742f2f25da67bddULL,0xef933bdc77c94195ULL,0xeaedd9156e240867ULL,
+	0x75c96e8f264e20e8ULL,0xabe6bfed59a7a841ULL,0x2cc09c0444c8eb00ULL,0xe05b3080f0c4e16bULL,0x1eb7777aa45f3314ULL,0x56af7bedce5d45e3ULL,0x2b6e019a88b12f1aULL,0x086659cdfd835f9bULL,
+	0xea7d260a6245e404ULL,0x9de407956e7fdfe0ULL,0x1ff3a4158dac1ab5ULL,0x3e7090f1649c9073ULL,0x1a7685612b944e88ULL,0x250f939ee57f61c8ULL,0x0c0daa891ead643dULL,0x68930023e125b88eULL,
+	0xccc425634b2ed709ULL,0x0e356769856fd30dULL,0xbcbcd43f559e9811ULL,0x738477ac5395b759ULL,0x35752b90c00ee17fULL,0x68748390742ed2e3ULL,0x7cd06422bd1f5bc1ULL,0xfbc08769c9e7b797ULL,
+	0x72bcd8b7bc60055bULL,0x03cc23ee56e27e4bULL,0xee337424e4819370ULL,0xe2aa0e430ad3da09ULL,0x40b8524f6383c45dULL,0xd766355442a41b25ULL,0x64efa6de778a4797ULL,0x2042170a7079adf4ULL,
+	0x97091dcbd53c5c9dULL,0xf17624b6ac0a177bULL,0xb0f139752cfe2dffULL,0xc1a35c0a6c7a574eULL,0x227d314693e79987ULL,0x0575bf30e89cb80eULL,0x2f4e247f0d1883bbULL,0xebd512263274c3d0ULL,
+	0xfea912baa5659ae8ULL,0x68363aba25e1a16eULL,0xb8842277752c41acULL,0xfe545c282897c3fcULL,0x2d36e9e7dc4c696bULL,0x5806244afba977c5ULL,0x85665e9be39508c1ULL,0xf720ee256d12597bULL,
+	0x562e4cecc135b208ULL,0x74e1b2654783f47dULL,0x6d2a506c5a3f3b30ULL,0xecead9f4c16762fcULL,0xf29dd4b2e286e5b9ULL,0x1b0fadc083bb3c61ULL,0x7a75023e7fac29a4ULL,0xc086d5f1c9477fa3ULL,
+	0xf4f876532de45068ULL,0x37c7a7e89e2e1f6eULL,0xd0825fa2a3584069ULL,0xaf2cea7c1727bf42ULL,0x0360a4fb9e4785a9ULL,0xe5fda49c27299f4aULL,0x48068e1371ac2f71ULL,0x83d0687b9077666fULL,
+	0xa4a319acd837879fULL,0x6fc1b49eed6b67b0ULL,0xe395993332f1f3afULL,0x966742eb65432a2eULL,0x4b8dc9feb4966228ULL,0x96cc631243f43950ULL,0x12068859c9b731eeULL,0x7b948dc356f79968ULL,
+	0x042c2af497e2feb4ULL,0xd36a42d7aebf7313ULL,0x49d2c9eb084ffdd7ULL,0x9f8aa54b2ef7c76aULL,0x9200b7ba09895e70ULL,0x3bd0c66fddb7fb58ULL,0x2d97d10878eb4cbbULL,0x2d431068d84bde31ULL,
+	0x5e5db46acb66e132ULL,0xf1be963a0d925880ULL,0x944a70270317b9e2ULL,0xe266f95948603d48ULL,0x98db66735c208899ULL,0x90472447a2fb18a3ULL,0x8a966939777c619fULL,0x3798142a2a3be21bULL,
+	0xe2f73c696755ff89ULL,0xdd3cf7e7473017e6ULL,0x8ef5689d3cf7600dULL,0x948dc4f8b1fc87b4ULL,0xd9e9fe814ea53299ULL,0x2d921ca298eb6028ULL,0xfaecedfd0c9803fcULL,0xf38ae8914d7b4745ULL,
+	0x871514560f664534ULL,0x85ceae7c4b68f103ULL,0xac09c4ae65578ab9ULL,0x33ec6868f044b10cULL,0x6ac4832b3a8ec1f1ULL,0x5509d1285847d5efULL,0xf909604f763f1574ULL,0xb16c4303c32f63c4ULL,
+	0xfd16847fdec67ef5ULL,0x742ee464233e76b7ULL,0x0b8e4134efc2b4c8ULL,0xca640b8642a3e521ULL,0x653a01908ceb6aa9ULL,0x313c300c547852d5ULL,0x24e4ab126b237af7ULL,0x2ba901628bb47af8ULL,
+	0x00467bc58cce08b5ULL,0xb636458c7f178d55ULL,0xc5748baea677d806ULL,0x2763a387dfa394ebULL,0xa12b448a7d3cebb6ULL,0xe7adda3e6f20d850ULL,0xf63ebce51558462cULL,0x58b36143620088a8ULL,
+	0xa9d89488a059c142ULL,0x6f5ae714ff0b9346ULL,0x068f237d16fb3664ULL,0x5853e4c4363186acULL,0xe2d87d2363c52f98ULL,0x2ec4a76681828876ULL,0x47b864fae14e7b1cULL,0x0c0bc0e569192408ULL,
+	0x624d60492ed22e91ULL,0x6fdfe0b56f072822ULL,0xeeca111539ce2271ULL,0x98100a4fdb01614fULL,0xb6b0daa2a35c628fULL,0xb6f94d2ec87e9a47ULL,0xc67732591d57d9ceULL,0xf70bfeec03884a7bULL,
+	0x4ff23ffd248a7d06ULL,0x80c5bfb4878873faULL,0xb7d9ad9005745981ULL,0x179c85db3db01994ULL,0xba41b06261a6966cULL,0x4d82d052eadce5a8ULL,0x9e91cd3ba5e6a318ULL,0x47795f4f95b2dda0ULL,
+	0x1ee426ccd5cd79bfULL,0x0032940b946c6e18ULL,0x1b1e8ae057477f58ULL,0xe94f7d346d823278ULL,0xc747cb96782ba21aULL,0xc5254469f72b33a5ULL,0x772ef6dec7f80c81ULL,0xd73acbfe2cd9e6b5ULL,
+	0x283c7513caa76097ULL,0x0a624fa936c83906ULL,0x6b20afec715af2c7ULL,0x4b969974eba78bfdULL,0x220755ccd921d60eULL,0x9b944e107baeca13ULL,0x04819d515ded93d4ULL,0x9bbff86e6dddfd27ULL,
+	0x21950b421ff6acd3ULL,0xffe7048453dc6909ULL,0xff4cd0b228766127ULL,0xabdbe6084fb7db2bULL,0x837c92285e1109e8ULL,0x26147d27f4645b5aULL,0x4d78f592f7818ed8ULL,0xd394077ef247fa36ULL,
+	0x508cec1c3b3f64c9ULL,0xe20bc0ba1e5edf3fULL,0xda1deb852f4318d4ULL,0xd20ebe0d5c3fa443ULL,0x370b4ea773241ea3ULL,0x61f1511c5e1a5f65ULL,0x99a5e23d82681c62ULL,0xd731e383a2f54c2dULL,
+	0x97359638546c4d8dULL,0x5f9c3fc492f24679ULL,0x912e8beda8c8acd9ULL,0xec3a318d306634b0ULL,0x80167f41c31cb264ULL,0x3db82f6f522113f2ULL,0xb155bcd2dcafe197ULL,0xfba1da5943465283ULL,
+	0x258bbbf9e7305683ULL,0x31eea5bf07ef5be6ULL,0x0deb0e4a46c814c1ULL,0x5cee8449a7b730ddULL,0xeab495c5a0182bdeULL,0xee759f879e27a6b4ULL,0xc2cf6a6880e518caULL,0x25e8013ff14cf3f4ULL,
+	0x3ec832e77acaca28ULL,0x1bfeea57c7385b29ULL,0x068212e3fd1eaf38ULL,0xc13298306acf8cccULL,0xb909f2db2aac9e59ULL,0x5748060db661782aULL,0xc5ab2632c79b7a01ULL,0xda44c6c600017626ULL,
+	0x69d44ed65c46aa8eULL,0x2100d5d3a8d063d1ULL,0xcb9727eaa2d17c36ULL,0x4c2bab1b8add53b7ULL,0xa084e90c15426704ULL,0x778afcd3a837ebeaULL,0x6651f7017ce477f8ULL,0xa062499846fb7a8bULL,
+	0x3667eb1a7f4c04ccULL,0x59556621a9404f84ULL,0x71cdf6537eceb50aULL,0x994a44a69b8335faULL,0xd7faf819dbeb9b69ULL,0x473c5680eed4350dULL,0xb6658466da44bba2ULL,0x0d1bc780872bdbf3ULL,
+	0xb8d3d9319ff91fe5ULL,0x039c4800f0518eedULL,0x95c376329182cb26ULL,0x0763a43482fc568dULL,0x707c04d5383e76baULL,0xac98b930824e8197ULL,0x92bf7c8f91230de0ULL,0x90876a0140959b70ULL,
+};
diff --git a/cbits/s2n/README.md b/cbits/s2n/README.md
--- a/cbits/s2n/README.md
+++ b/cbits/s2n/README.md
@@ -48,6 +48,49 @@
   the fallback for processors without them.  That *is* a feature bit, so the
   choice is made at run time, from `crypton_x86_simd_features()`.
 
+## RSA
+
+`crypton_powm.c`'s modular exponentiation also borrows from here, but only its
+innermost step and only on x86-64: `bignum_kmul_16_32`, `bignum_ksqr_16_32`,
+`bignum_kmul_32_64`, `bignum_ksqr_32_64` and `bignum_emontredc_8n` replace the
+C's Montgomery multiplication and square.  The window, the table and its masked
+scan are crypton's throughout.  Sixteen limbs is 1024 bits and thirty-two is
+2048: the halves a CRT exponentiation works in for RSA-2048 and RSA-4096, and
+the whole thing without CRT.  The reduction wants ADX, so the choice is made at
+run time like the other x86-64 ones.
+
+It is twice the C, because the C cannot form the two carry chains `ADCX` and
+`ADOX` give.  Measured on an EPYC 7763 at 1024 bits:
+
+| | C | s2n-bignum |
+| --- | ---: | ---: |
+| multiplication | 0.4832 us | **0.2479** |
+| square | 0.3984 | **0.1994** |
+
+**Nothing is vendored for AArch64**, where the same five routines measure level
+with the C.  That took three attempts to establish, and the first two were
+wrong in opposite directions: a reading when the x86-64 routines went in put
+the C 5% ahead, and one on 2026-09-26 put the assembly 4% ahead.  Both were
+wall-clock times on a machine with other work on it, where a swing of that size
+says nothing.  Measured by thread CPU time, taking the best of twenty-five
+batches and alternating the two binaries with the order swapped, one RSA-2048
+CRT private operation is 598.9 us through the C and 597.7 through the assembly:
+two tenths of a per cent, which is nothing.  The two agree on 200 random cases
+at 1024 and 2048 bits, so both were computing the same thing.  Five files for
+nothing is not a trade, so the C stays.
+
+The gap to OpenSSL on Apple silicon -- about half its speed -- is assembly and
+not the C, and no portable C closes it.  BearSSL's `i62`, which is as far as
+portable C is known to go -- 62-bit limbs in 64-bit words, so that a
+multiply-accumulate fits an `__int128` with no carry chain at all, and a
+five-bit window against crypton's four -- was built and measured the same way
+on the same machine: 626.4 us against crypton's C at 668.0, a tie.
+
+`bignum_emontredc_8n_cdiff` was tried too and is not the answer either: it
+wants a precomputation this test did not give it, and was slower besides.  What
+the window is worth, and why it is four and not five, is in
+`cbits/crypton_powm.c` beside the constant.
+
 ## What is not here
 
 s2n-bignum has only x86-64 and AArch64, so crypton's C stays and is what
diff --git a/cbits/s2n/arm/bignum_demont_p256.S b/cbits/s2n/arm/bignum_demont_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/bignum_demont_p256.S
@@ -0,0 +1,99 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced
+// Input x[4]; output z[4]
+//
+//    extern void bignum_demont_p256(uint64_t z[static 4],
+//                                   const uint64_t x[static 4]);
+//
+// This assumes the input is < p_256 for correctness. If this is not the case,
+// use the variant "bignum_deamont_p256" instead.
+//
+// Standard ARM ABI: X0 = z, X1 = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_demont_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_demont_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_demont_p256)
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_demont_p256_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_demont_p256_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_demont_p256_alt)
+        .text
+        .balign 4
+
+// ---------------------------------------------------------------------------
+// Core one-step "short" Montgomery reduction macro. Takes input in
+// [d3;d2;d1;d0] and returns result in [d4;d3;d2;d1], adding to the
+// existing contents of [d3;d2;d1] and generating d4 from zero, re-using
+// d0 as a temporary internally together with t0, t1 and t2.
+// It is fine for d4 to be the same register as d0, and it often is.
+// ---------------------------------------------------------------------------
+
+#define montreds(d4,d3,d2,d1,d0, t2,t1,t0)                                  \
+/* Let w = d0, the original word we use as offset; d0 gets recycled      */ \
+/* First let [t2;t1] = 2^32 * w                                          */ \
+/* then let [d0;t0] = (2^64 - 2^32 + 1) * w (overwrite old d0)           */ \
+        lsl     t1, d0, #32 __LF                                       \
+        subs    t0, d0, t1 __LF                                        \
+        lsr     t2, d0, #32 __LF                                       \
+        sbc     d0, d0, t2 __LF                                        \
+/* Hence [d4;..;d1] := [d3;d2;d1;0] + (2^256 - 2^224 + 2^192 + 2^96) * w */ \
+        adds    d1, d1, t1 __LF                                        \
+        adcs    d2, d2, t2 __LF                                        \
+        adcs    d3, d3, t0 __LF                                        \
+        adc     d4, d0, xzr
+
+// Input parameters
+
+#define z x0
+#define x x1
+
+// Rotating registers for the intermediate windows (with repetitions)
+
+#define d0 x2
+#define d1 x3
+#define d2 x4
+#define d3 x5
+
+// Other temporaries
+
+#define u x6
+#define v x7
+#define w x8
+
+S2N_BN_SYMBOL(bignum_demont_p256):
+
+S2N_BN_SYMBOL(bignum_demont_p256_alt):
+        CFI_START
+
+// Set up an initial window with the input x and an extra leading zero
+
+        ldp     d0, d1, [x]
+        ldp     d2, d3, [x, #16]
+
+// Systematically scroll left doing 1-step reductions
+
+        montreds(d0,d3,d2,d1,d0, u,v,w)
+
+        montreds(d1,d0,d3,d2,d1, u,v,w)
+
+        montreds(d2,d1,d0,d3,d2, u,v,w)
+
+        montreds(d3,d2,d1,d0,d3, u,v,w)
+
+// Write back result
+
+        stp     d0, d1, [z]
+        stp     d2, d3, [z, #16]
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_demont_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/arm/bignum_neg_p256.S b/cbits/s2n/arm/bignum_neg_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/bignum_neg_p256.S
@@ -0,0 +1,72 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced
+// Input x[4]; output z[4]
+//
+//    extern void bignum_neg_p256(uint64_t z[static 4], const uint64_t x[static 4]);
+//
+// Standard ARM ABI: X0 = z, X1 = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_neg_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_neg_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_neg_p256)
+        .text
+        .balign 4
+
+#define z x0
+#define x x1
+
+#define p x2
+#define t x3
+
+#define d0 x4
+#define d1 x5
+#define d2 x6
+#define d3 x7
+
+
+S2N_BN_SYMBOL(bignum_neg_p256):
+        CFI_START
+
+// Load the 4 digits of x
+
+        ldp     d0, d1, [x]
+        ldp     d2, d3, [x, #16]
+
+// Set a bitmask p for the input being nonzero, so that we avoid doing
+// -0 = p_256 and hence maintain strict modular reduction
+
+        orr     t, d0, d1
+        orr     p, d2, d3
+        orr     p, p, t
+        cmp     p, #0
+        csetm   p, ne
+
+// Mask the nontrivial words of p_256 = [n3;0;n1;-1] and subtract
+
+        subs    d0, p, d0
+        and     t, p, #0x00000000ffffffff
+        sbcs    d1, t, d1
+        sbcs    d2, xzr, d2
+        and     t, p, #0xffffffff00000001
+        sbc     d3, t, d3
+
+// Write back the result
+
+        stp     d0, d1, [z]
+        stp     d2, d3, [z, #16]
+
+// Return
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_neg_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/arm/bignum_tomont_p256.S b/cbits/s2n/arm/bignum_tomont_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/bignum_tomont_p256.S
@@ -0,0 +1,122 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert to Montgomery form z := (2^256 * x) mod p_256
+// Input x[4]; output z[4]
+//
+//    extern void bignum_tomont_p256(uint64_t z[static 4],
+//                                   const uint64_t x[static 4]);
+//
+// Standard ARM ABI: X0 = z, X1 = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_tomont_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_tomont_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_tomont_p256)
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_tomont_p256_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_tomont_p256_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_tomont_p256_alt)
+        .text
+        .balign 4
+
+// ----------------------------------------------------------------------------
+// Core "x |-> (2^64 * x) mod p_256" macro, with x assumed to be < p_256.
+// Input is in [d4;d3;d2;d1] and output in [d3;d2;d1;d0]
+// using d4 as well as t1, t2, t3 as temporaries.
+// ----------------------------------------------------------------------------
+
+#define modstep_p256(d4, d3,d2,d1,d0, t1,t2,t3)                             \
+/* Writing the input as z = 2^256 * h + 2^192 * l + t = 2^192 * hl + t,  */ \
+/* our quotient approximation is MIN ((hl + hl>>32 + 1)>>64) (2^64 - 1). */ \
+        subs    xzr, xzr, xzr __LF/* Set carry flag for +1 */          \
+        extr    t3, d4, d3, #32 __LF                                   \
+        adcs    xzr, d3, t3 __LF                                       \
+        lsr     t3, d4, #32 __LF                                       \
+        adcs    t3, d4, t3 __LF                                        \
+        csetm   d0, cs __LF                                            \
+        orr     t3, t3, d0 __LF                                        \
+/* First do [t2;t1] = 2^32 * q, which we use twice                       */ \
+        lsl     t1, t3, #32 __LF                                       \
+        lsr     t2, t3, #32 __LF                                       \
+/* Add 2^224 * q to sum                                                  */ \
+        adds    d3, d3, t1 __LF                                        \
+        adc     d4, d4, t2 __LF                                        \
+/* Accumulate [t2;t1;d0] = (2^96 - 1) * q                                */ \
+        subs    d0, xzr, t3 __LF                                       \
+        sbcs    t1, t1, xzr __LF                                       \
+        sbc     t2, t2, xzr __LF                                       \
+/* Subtract (2^256 + 2^192 + 2^96 - 1) * q                               */ \
+        subs    d0, xzr, d0 __LF                                       \
+        sbcs    d1, d1, t1 __LF                                        \
+        sbcs    d2, d2, t2 __LF                                        \
+        sbcs    d3, d3, t3 __LF                                        \
+        sbcs    d4, d4, t3 __LF                                        \
+/* Use top word as mask to correct                                       */ \
+        adds    d0, d0, d4 __LF                                        \
+        mov     t1, #0x00000000ffffffff __LF                           \
+        and     t1, t1, d4 __LF                                        \
+        adcs    d1, d1, t1 __LF                                        \
+        adcs    d2, d2, xzr __LF                                       \
+        mov     t1, #0xffffffff00000001 __LF                           \
+        and     t1, t1, d4 __LF                                        \
+        adc     d3, d3, t1
+
+#define d0 x2
+#define d1 x3
+#define d2 x4
+#define d3 x5
+#define d4 x6
+
+#define t0 x1
+#define t1 x7
+#define t2 x8
+#define t3 x9
+
+S2N_BN_SYMBOL(bignum_tomont_p256):
+
+S2N_BN_SYMBOL(bignum_tomont_p256_alt):
+        CFI_START
+
+// Load the input
+
+        ldp     d0, d1, [x1]
+        ldp     d2, d3, [x1, #16]
+
+// Do an initial reduction to make sure this is < p_256, using just
+// a copy of the bignum_mod_p256_4 code. This is needed to set up the
+// invariant "input < p_256" for the main modular reduction steps.
+
+        mov     t0, #0xffffffffffffffff
+        mov     t1, #0x00000000ffffffff
+        mov     t3, #0xffffffff00000001
+        subs    t0, d0, t0
+        sbcs    t1, d1, t1
+        sbcs    t2, d2, xzr
+        sbcs    t3, d3, t3
+        csel    d0, d0, t0, cc
+        csel    d1, d1, t1, cc
+        csel    d2, d2, t2, cc
+        csel    d3, d3, t3, cc
+
+// Successively multiply by 2^64 and reduce
+
+        modstep_p256(d3,d2,d1,d0,d4, t1,t2,t3)
+        modstep_p256(d2,d1,d0,d4,d3, t1,t2,t3)
+        modstep_p256(d1,d0,d4,d3,d2, t1,t2,t3)
+        modstep_p256(d0,d4,d3,d2,d1, t1,t2,t3)
+
+// Store the result and return
+
+        stp     d1, d2, [x0]
+        stp     d3, d4, [x0, #16]
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_tomont_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/arm/edwards25519_encode.S b/cbits/s2n/arm/edwards25519_encode.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/edwards25519_encode.S
@@ -0,0 +1,136 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Encode edwards25519 point into compressed form as 256-bit number
+// Input p[8]; output z[32] (bytes)
+//
+//    extern void edwards25519_encode(uint8_t z[static 32],
+//                                    const uint64_t p[static 8]);
+//
+// This assumes that the input buffer p points to a pair of 256-bit
+// numbers x (at p) and y (at p+4) representing a point (x,y) on the
+// edwards25519 curve. It is assumed that both x and y are < p_25519
+// but there is no checking of this, nor of the fact that (x,y) is
+// in fact on the curve.
+//
+// The output in z is a little-endian array of bytes corresponding to
+// the standard compressed encoding of a point as 2^255 * x_0 + y
+// where x_0 is the least significant bit of x.
+// See "https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2"
+// In this implementation, y is simply truncated to 255 bits, but if
+// it is reduced mod p_25519 as expected this does not affect values.
+//
+// Standard ARM ABI: X0 = z, X1 = p
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_encode)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_encode)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_encode)
+        .text
+        .balign 4
+
+#define z x0
+#define p x1
+
+#define y0 x2
+#define y1 x3
+#define y2 x4
+#define y3 x5
+#define y0short w2
+#define y1short w3
+#define y2short w4
+#define y3short w5
+#define xb x6
+
+S2N_BN_SYMBOL(edwards25519_encode):
+        CFI_START
+
+// Load lowest word of x coordinate in xb and full y as [y3;y2;y1;y0].
+
+        ldr     xb, [p]
+        ldp     y0, y1, [p, #32]
+        ldp     y2, y3, [p, #48]
+
+// Compute the encoded form, making the LSB of x the MSB of the encoding
+
+        and     y3, y3, #0x7FFFFFFFFFFFFFFF
+        orr     y3, y3, xb, lsl #63
+
+// Write back in a byte-oriented fashion to be independent of endianness
+
+        strb    y0short, [z]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #1]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #2]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #3]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #4]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #5]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #6]
+        lsr     y0, y0, #8
+        strb    y0short, [z, #7]
+
+        strb    y1short, [z, #8]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #9]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #10]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #11]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #12]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #13]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #14]
+        lsr     y1, y1, #8
+        strb    y1short, [z, #15]
+
+        strb    y2short, [z, #16]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #17]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #18]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #19]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #20]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #21]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #22]
+        lsr     y2, y2, #8
+        strb    y2short, [z, #23]
+
+        strb    y3short, [z, #24]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #25]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #26]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #27]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #28]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #29]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #30]
+        lsr     y3, y3, #8
+        strb    y3short, [z, #31]
+
+// Return
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_encode)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/arm/edwards25519_scalarmulbase.S b/cbits/s2n/arm/edwards25519_scalarmulbase.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/edwards25519_scalarmulbase.S
@@ -0,0 +1,9635 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Scalar multiplication for the edwards25519 standard basepoint
+// Input scalar[4]; output res[8]
+//
+// extern void edwards25519_scalarmulbase
+//   (uint64_t res[static 8],const uint64_t scalar[static 4]);
+//
+// Given a scalar n, returns point (X,Y) = n * B where B = (...,4/5) is
+// the standard basepoint for the edwards25519 (Ed25519) curve.
+//
+// Standard ARM ABI: X0 = res, X1 = scalar
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_scalarmulbase)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_scalarmulbase)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_scalarmulbase)
+
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable home for the input result argument during the whole body
+
+#define res x23
+
+// Other variables that are only needed prior to the modular inverse.
+
+#define tab x19
+
+#define i x20
+
+#define bias x21
+
+#define bf x22
+#define ix x22
+
+// Pointer-offset pairs for result and temporaries on stack with some aliasing.
+
+#define resx res, #(0*NUMSIZE)
+#define resy res, #(1*NUMSIZE)
+
+#define scalar sp, #(0*NUMSIZE)
+
+#define tabent sp, #(1*NUMSIZE)
+#define ymx_2 sp, #(1*NUMSIZE)
+#define xpy_2 sp, #(2*NUMSIZE)
+#define kxy_2 sp, #(3*NUMSIZE)
+
+#define acc sp, #(4*NUMSIZE)
+#define x_1 sp, #(4*NUMSIZE)
+#define y_1 sp, #(5*NUMSIZE)
+#define z_1 sp, #(6*NUMSIZE)
+#define w_1 sp, #(7*NUMSIZE)
+#define x_3 sp, #(4*NUMSIZE)
+#define y_3 sp, #(5*NUMSIZE)
+#define z_3 sp, #(6*NUMSIZE)
+#define w_3 sp, #(7*NUMSIZE)
+
+#define tmpspace sp, #(8*NUMSIZE)
+#define t0 sp, #(8*NUMSIZE)
+#define t1 sp, #(9*NUMSIZE)
+#define t2 sp, #(10*NUMSIZE)
+#define t3 sp, #(11*NUMSIZE)
+#define t4 sp, #(12*NUMSIZE)
+#define t5 sp, #(13*NUMSIZE)
+
+// Total size to reserve on the stack
+
+#define NSPACE 14*NUMSIZE
+
+// Load 64-bit immediate into a register
+
+#define movbig(nn,n3,n2,n1,n0)                                      \
+        movz    nn, n0 __LF                                            \
+        movk    nn, n1, lsl #16 __LF                                   \
+        movk    nn, n2, lsl #32 __LF                                   \
+        movk    nn, n3, lsl #48
+
+// Macro wrapping up the basic field operation bignum_mul_p25519, only
+// trivially different from a pure function call to that subroutine.
+
+#define mul_p25519(P0,P1,P2)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x5, x6, [P2] __LF                  \
+        umull   x7, w3, w5 __LF                    \
+        lsr     x0, x3, #32 __LF                   \
+        umull   x15, w0, w5 __LF                   \
+        lsr     x16, x5, #32 __LF                  \
+        umull   x8, w16, w0 __LF                   \
+        umull   x16, w3, w16 __LF                  \
+        adds    x7, x7, x15, lsl #32 __LF          \
+        lsr     x15, x15, #32 __LF                 \
+        adc     x8, x8, x15 __LF                   \
+        adds    x7, x7, x16, lsl #32 __LF          \
+        lsr     x16, x16, #32 __LF                 \
+        adc     x8, x8, x16 __LF                   \
+        mul     x9, x4, x6 __LF                    \
+        umulh   x10, x4, x6 __LF                   \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x16, cc __LF                       \
+        adds    x9, x9, x8 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        subs    x3, x5, x6 __LF                    \
+        cneg    x3, x3, cc __LF                    \
+        cinv    x16, x16, cc __LF                  \
+        mul     x15, x4, x3 __LF                   \
+        umulh   x3, x4, x3 __LF                    \
+        adds    x8, x7, x9 __LF                    \
+        adcs    x9, x9, x10 __LF                   \
+        adc     x10, x10, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x8, x15, x8 __LF                   \
+        eor     x3, x3, x16 __LF                   \
+        adcs    x9, x3, x9 __LF                    \
+        adc     x10, x10, x16 __LF                 \
+        ldp     x3, x4, [P1+16] __LF               \
+        ldp     x5, x6, [P2+16] __LF               \
+        umull   x11, w3, w5 __LF                   \
+        lsr     x0, x3, #32 __LF                   \
+        umull   x15, w0, w5 __LF                   \
+        lsr     x16, x5, #32 __LF                  \
+        umull   x12, w16, w0 __LF                  \
+        umull   x16, w3, w16 __LF                  \
+        adds    x11, x11, x15, lsl #32 __LF        \
+        lsr     x15, x15, #32 __LF                 \
+        adc     x12, x12, x15 __LF                 \
+        adds    x11, x11, x16, lsl #32 __LF        \
+        lsr     x16, x16, #32 __LF                 \
+        adc     x12, x12, x16 __LF                 \
+        mul     x13, x4, x6 __LF                   \
+        umulh   x14, x4, x6 __LF                   \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x16, cc __LF                       \
+        adds    x13, x13, x12 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        subs    x3, x5, x6 __LF                    \
+        cneg    x3, x3, cc __LF                    \
+        cinv    x16, x16, cc __LF                  \
+        mul     x15, x4, x3 __LF                   \
+        umulh   x3, x4, x3 __LF                    \
+        adds    x12, x11, x13 __LF                 \
+        adcs    x13, x13, x14 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x12, x15, x12 __LF                 \
+        eor     x3, x3, x16 __LF                   \
+        adcs    x13, x3, x13 __LF                  \
+        adc     x14, x14, x16 __LF                 \
+        ldp     x3, x4, [P1+16] __LF               \
+        ldp     x15, x16, [P1] __LF                \
+        subs    x3, x3, x15 __LF                   \
+        sbcs    x4, x4, x16 __LF                   \
+        csetm   x16, cc __LF                       \
+        ldp     x15, x0, [P2] __LF                 \
+        subs    x5, x15, x5 __LF                   \
+        sbcs    x6, x0, x6 __LF                    \
+        csetm   x0, cc __LF                        \
+        eor     x3, x3, x16 __LF                   \
+        subs    x3, x3, x16 __LF                   \
+        eor     x4, x4, x16 __LF                   \
+        sbc     x4, x4, x16 __LF                   \
+        eor     x5, x5, x0 __LF                    \
+        subs    x5, x5, x0 __LF                    \
+        eor     x6, x6, x0 __LF                    \
+        sbc     x6, x6, x0 __LF                    \
+        eor     x16, x0, x16 __LF                  \
+        adds    x11, x11, x9 __LF                  \
+        adcs    x12, x12, x10 __LF                 \
+        adcs    x13, x13, xzr __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        mul     x2, x3, x5 __LF                    \
+        umulh   x0, x3, x5 __LF                    \
+        mul     x15, x4, x6 __LF                   \
+        umulh   x1, x4, x6 __LF                    \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x9, cc __LF                        \
+        adds    x15, x15, x0 __LF                  \
+        adc     x1, x1, xzr __LF                   \
+        subs    x6, x5, x6 __LF                    \
+        cneg    x6, x6, cc __LF                    \
+        cinv    x9, x9, cc __LF                    \
+        mul     x5, x4, x6 __LF                    \
+        umulh   x6, x4, x6 __LF                    \
+        adds    x0, x2, x15 __LF                   \
+        adcs    x15, x15, x1 __LF                  \
+        adc     x1, x1, xzr __LF                   \
+        cmn     x9, #0x1 __LF                      \
+        eor     x5, x5, x9 __LF                    \
+        adcs    x0, x5, x0 __LF                    \
+        eor     x6, x6, x9 __LF                    \
+        adcs    x15, x6, x15 __LF                  \
+        adc     x1, x1, x9 __LF                    \
+        adds    x9, x11, x7 __LF                   \
+        adcs    x10, x12, x8 __LF                  \
+        adcs    x11, x13, x11 __LF                 \
+        adcs    x12, x14, x12 __LF                 \
+        adcs    x13, x13, xzr __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x2, x2, x16 __LF                   \
+        adcs    x9, x2, x9 __LF                    \
+        eor     x0, x0, x16 __LF                   \
+        adcs    x10, x0, x10 __LF                  \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x11, x15, x11 __LF                 \
+        eor     x1, x1, x16 __LF                   \
+        adcs    x12, x1, x12 __LF                  \
+        adcs    x13, x13, x16 __LF                 \
+        adc     x14, x14, x16 __LF                 \
+        mov     x3, #0x26 __LF                     \
+        umull   x4, w11, w3 __LF                   \
+        add     x4, x4, w7, uxtw __LF              \
+        lsr     x7, x7, #32 __LF                   \
+        lsr     x11, x11, #32 __LF                 \
+        umaddl  x11, w11, w3, x7 __LF              \
+        mov     x7, x4 __LF                        \
+        umull   x4, w12, w3 __LF                   \
+        add     x4, x4, w8, uxtw __LF              \
+        lsr     x8, x8, #32 __LF                   \
+        lsr     x12, x12, #32 __LF                 \
+        umaddl  x12, w12, w3, x8 __LF              \
+        mov     x8, x4 __LF                        \
+        umull   x4, w13, w3 __LF                   \
+        add     x4, x4, w9, uxtw __LF              \
+        lsr     x9, x9, #32 __LF                   \
+        lsr     x13, x13, #32 __LF                 \
+        umaddl  x13, w13, w3, x9 __LF              \
+        mov     x9, x4 __LF                        \
+        umull   x4, w14, w3 __LF                   \
+        add     x4, x4, w10, uxtw __LF             \
+        lsr     x10, x10, #32 __LF                 \
+        lsr     x14, x14, #32 __LF                 \
+        umaddl  x14, w14, w3, x10 __LF             \
+        mov     x10, x4 __LF                       \
+        lsr     x0, x14, #31 __LF                  \
+        mov     x5, #0x13 __LF                     \
+        umaddl  x5, w5, w0, x5 __LF                \
+        add     x7, x7, x5 __LF                    \
+        adds    x7, x7, x11, lsl #32 __LF          \
+        extr    x3, x12, x11, #32 __LF             \
+        adcs    x8, x8, x3 __LF                    \
+        extr    x3, x13, x12, #32 __LF             \
+        adcs    x9, x9, x3 __LF                    \
+        extr    x3, x14, x13, #32 __LF             \
+        lsl     x5, x0, #63 __LF                   \
+        eor     x10, x10, x5 __LF                  \
+        adc     x10, x10, x3 __LF                  \
+        mov     x3, #0x13 __LF                     \
+        tst     x10, #0x8000000000000000 __LF      \
+        csel    x3, x3, xzr, pl __LF               \
+        subs    x7, x7, x3 __LF                    \
+        sbcs    x8, x8, xzr __LF                   \
+        sbcs    x9, x9, xzr __LF                   \
+        sbc     x10, x10, xzr __LF                 \
+        and     x10, x10, #0x7fffffffffffffff __LF \
+        stp     x7, x8, [P0] __LF                  \
+        stp     x9, x10, [P0+16]
+
+// A version of multiplication that only guarantees output < 2 * p_25519.
+// This basically skips the +1 and final correction in quotient estimation.
+
+#define mul_4(P0,P1,P2)                         \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x5, x6, [P2] __LF                  \
+        umull   x7, w3, w5 __LF                    \
+        lsr     x0, x3, #32 __LF                   \
+        umull   x15, w0, w5 __LF                   \
+        lsr     x16, x5, #32 __LF                  \
+        umull   x8, w16, w0 __LF                   \
+        umull   x16, w3, w16 __LF                  \
+        adds    x7, x7, x15, lsl #32 __LF          \
+        lsr     x15, x15, #32 __LF                 \
+        adc     x8, x8, x15 __LF                   \
+        adds    x7, x7, x16, lsl #32 __LF          \
+        lsr     x16, x16, #32 __LF                 \
+        adc     x8, x8, x16 __LF                   \
+        mul     x9, x4, x6 __LF                    \
+        umulh   x10, x4, x6 __LF                   \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x16, cc __LF                       \
+        adds    x9, x9, x8 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        subs    x3, x5, x6 __LF                    \
+        cneg    x3, x3, cc __LF                    \
+        cinv    x16, x16, cc __LF                  \
+        mul     x15, x4, x3 __LF                   \
+        umulh   x3, x4, x3 __LF                    \
+        adds    x8, x7, x9 __LF                    \
+        adcs    x9, x9, x10 __LF                   \
+        adc     x10, x10, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x8, x15, x8 __LF                   \
+        eor     x3, x3, x16 __LF                   \
+        adcs    x9, x3, x9 __LF                    \
+        adc     x10, x10, x16 __LF                 \
+        ldp     x3, x4, [P1+16] __LF               \
+        ldp     x5, x6, [P2+16] __LF               \
+        umull   x11, w3, w5 __LF                   \
+        lsr     x0, x3, #32 __LF                   \
+        umull   x15, w0, w5 __LF                   \
+        lsr     x16, x5, #32 __LF                  \
+        umull   x12, w16, w0 __LF                  \
+        umull   x16, w3, w16 __LF                  \
+        adds    x11, x11, x15, lsl #32 __LF        \
+        lsr     x15, x15, #32 __LF                 \
+        adc     x12, x12, x15 __LF                 \
+        adds    x11, x11, x16, lsl #32 __LF        \
+        lsr     x16, x16, #32 __LF                 \
+        adc     x12, x12, x16 __LF                 \
+        mul     x13, x4, x6 __LF                   \
+        umulh   x14, x4, x6 __LF                   \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x16, cc __LF                       \
+        adds    x13, x13, x12 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        subs    x3, x5, x6 __LF                    \
+        cneg    x3, x3, cc __LF                    \
+        cinv    x16, x16, cc __LF                  \
+        mul     x15, x4, x3 __LF                   \
+        umulh   x3, x4, x3 __LF                    \
+        adds    x12, x11, x13 __LF                 \
+        adcs    x13, x13, x14 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x12, x15, x12 __LF                 \
+        eor     x3, x3, x16 __LF                   \
+        adcs    x13, x3, x13 __LF                  \
+        adc     x14, x14, x16 __LF                 \
+        ldp     x3, x4, [P1+16] __LF               \
+        ldp     x15, x16, [P1] __LF                \
+        subs    x3, x3, x15 __LF                   \
+        sbcs    x4, x4, x16 __LF                   \
+        csetm   x16, cc __LF                       \
+        ldp     x15, x0, [P2] __LF                 \
+        subs    x5, x15, x5 __LF                   \
+        sbcs    x6, x0, x6 __LF                    \
+        csetm   x0, cc __LF                        \
+        eor     x3, x3, x16 __LF                   \
+        subs    x3, x3, x16 __LF                   \
+        eor     x4, x4, x16 __LF                   \
+        sbc     x4, x4, x16 __LF                   \
+        eor     x5, x5, x0 __LF                    \
+        subs    x5, x5, x0 __LF                    \
+        eor     x6, x6, x0 __LF                    \
+        sbc     x6, x6, x0 __LF                    \
+        eor     x16, x0, x16 __LF                  \
+        adds    x11, x11, x9 __LF                  \
+        adcs    x12, x12, x10 __LF                 \
+        adcs    x13, x13, xzr __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        mul     x2, x3, x5 __LF                    \
+        umulh   x0, x3, x5 __LF                    \
+        mul     x15, x4, x6 __LF                   \
+        umulh   x1, x4, x6 __LF                    \
+        subs    x4, x4, x3 __LF                    \
+        cneg    x4, x4, cc __LF                    \
+        csetm   x9, cc __LF                        \
+        adds    x15, x15, x0 __LF                  \
+        adc     x1, x1, xzr __LF                   \
+        subs    x6, x5, x6 __LF                    \
+        cneg    x6, x6, cc __LF                    \
+        cinv    x9, x9, cc __LF                    \
+        mul     x5, x4, x6 __LF                    \
+        umulh   x6, x4, x6 __LF                    \
+        adds    x0, x2, x15 __LF                   \
+        adcs    x15, x15, x1 __LF                  \
+        adc     x1, x1, xzr __LF                   \
+        cmn     x9, #0x1 __LF                      \
+        eor     x5, x5, x9 __LF                    \
+        adcs    x0, x5, x0 __LF                    \
+        eor     x6, x6, x9 __LF                    \
+        adcs    x15, x6, x15 __LF                  \
+        adc     x1, x1, x9 __LF                    \
+        adds    x9, x11, x7 __LF                   \
+        adcs    x10, x12, x8 __LF                  \
+        adcs    x11, x13, x11 __LF                 \
+        adcs    x12, x14, x12 __LF                 \
+        adcs    x13, x13, xzr __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        cmn     x16, #0x1 __LF                     \
+        eor     x2, x2, x16 __LF                   \
+        adcs    x9, x2, x9 __LF                    \
+        eor     x0, x0, x16 __LF                   \
+        adcs    x10, x0, x10 __LF                  \
+        eor     x15, x15, x16 __LF                 \
+        adcs    x11, x15, x11 __LF                 \
+        eor     x1, x1, x16 __LF                   \
+        adcs    x12, x1, x12 __LF                  \
+        adcs    x13, x13, x16 __LF                 \
+        adc     x14, x14, x16 __LF                 \
+        mov     x3, #0x26 __LF                     \
+        umull   x4, w11, w3 __LF                   \
+        add     x4, x4, w7, uxtw __LF              \
+        lsr     x7, x7, #32 __LF                   \
+        lsr     x11, x11, #32 __LF                 \
+        umaddl  x11, w11, w3, x7 __LF              \
+        mov     x7, x4 __LF                        \
+        umull   x4, w12, w3 __LF                   \
+        add     x4, x4, w8, uxtw __LF              \
+        lsr     x8, x8, #32 __LF                   \
+        lsr     x12, x12, #32 __LF                 \
+        umaddl  x12, w12, w3, x8 __LF              \
+        mov     x8, x4 __LF                        \
+        umull   x4, w13, w3 __LF                   \
+        add     x4, x4, w9, uxtw __LF              \
+        lsr     x9, x9, #32 __LF                   \
+        lsr     x13, x13, #32 __LF                 \
+        umaddl  x13, w13, w3, x9 __LF              \
+        mov     x9, x4 __LF                        \
+        umull   x4, w14, w3 __LF                   \
+        add     x4, x4, w10, uxtw __LF             \
+        lsr     x10, x10, #32 __LF                 \
+        lsr     x14, x14, #32 __LF                 \
+        umaddl  x14, w14, w3, x10 __LF             \
+        mov     x10, x4 __LF                       \
+        lsr     x0, x14, #31 __LF                  \
+        mov     x5, #0x13 __LF                     \
+        umull   x5, w5, w0 __LF                    \
+        add     x7, x7, x5 __LF                    \
+        adds    x7, x7, x11, lsl #32 __LF          \
+        extr    x3, x12, x11, #32 __LF             \
+        adcs    x8, x8, x3 __LF                    \
+        extr    x3, x13, x12, #32 __LF             \
+        adcs    x9, x9, x3 __LF                    \
+        extr    x3, x14, x13, #32 __LF             \
+        lsl     x5, x0, #63 __LF                   \
+        eor     x10, x10, x5 __LF                  \
+        adc     x10, x10, x3 __LF                  \
+        stp     x7, x8, [P0] __LF                  \
+        stp     x9, x10, [P0+16]
+
+// Modular subtraction with double modulus 2 * p_25519 = 2^256 - 38
+
+#define sub_twice4(P0,P1,P2)                    \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        mov     x4, #38 __LF                       \
+        csel    x3, x4, xzr, lo __LF               \
+        subs    x5, x5, x3 __LF                    \
+        sbcs    x6, x6, xzr __LF                   \
+        sbcs    x7, x7, xzr __LF                   \
+        sbc     x8, x8, xzr __LF                   \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+// Modular addition and doubling with double modulus 2 * p_25519 = 2^256 - 38.
+// This only ensures that the result fits in 4 digits, not that it is reduced
+// even w.r.t. double modulus. The result is always correct modulo provided
+// the sum of the inputs is < 2^256 + 2^256 - 38, so in particular provided
+// at least one of them is reduced double modulo.
+
+#define add_twice4(P0,P1,P2)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        adds    x3, x3, x7 __LF                    \
+        adcs    x4, x4, x8 __LF                    \
+        ldp     x5, x6, [P1+16] __LF               \
+        ldp     x7, x8, [P2+16] __LF               \
+        adcs    x5, x5, x7 __LF                    \
+        adcs    x6, x6, x8 __LF                    \
+        mov     x9, #38 __LF                       \
+        csel    x9, x9, xzr, cs __LF               \
+        adds    x3, x3, x9 __LF                    \
+        adcs    x4, x4, xzr __LF                   \
+        adcs    x5, x5, xzr __LF                   \
+        adc     x6, x6, xzr __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+#define double_twice4(P0,P1)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        adds    x3, x3, x3 __LF                    \
+        adcs    x4, x4, x4 __LF                    \
+        ldp     x5, x6, [P1+16] __LF               \
+        adcs    x5, x5, x5 __LF                    \
+        adcs    x6, x6, x6 __LF                    \
+        mov     x9, #38 __LF                       \
+        csel    x9, x9, xzr, cs __LF               \
+        adds    x3, x3, x9 __LF                    \
+        adcs    x4, x4, xzr __LF                   \
+        adcs    x5, x5, xzr __LF                   \
+        adc     x6, x6, xzr __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase):
+        CFI_START
+
+// Save regs and make room for temporaries
+
+        CFI_PUSH2(x19,x20)
+        CFI_PUSH2(x21,x22)
+        CFI_PUSH2(x23,x24)
+        CFI_DEC_SP(NSPACE)
+
+// Move the output pointer to a stable place
+
+        mov     res, x0
+
+// Copy the input scalar x to its local variable while reducing it
+// modulo 2^252 + m where m = 27742317777372353535851937790883648493;
+// this is the order of the basepoint so this doesn't change the result.
+// First do q = floor(x/2^252) and x' = x - q * (2^252 + m), which gives
+// an initial result -15 * m <= x' < 2^252
+
+        ldp     x10, x11, [x1]
+        ldp     x12, x13, [x1, #16]
+
+        lsr     x9, x13, #60
+
+        movbig(x0,#0x5812,#0x631a,#0x5cf5,#0xd3ed);
+        movbig(x1,#0x14de,#0xf9de,#0xa2f7,#0x9cd6);
+
+        mul     x2, x9, x0
+        mul     x3, x9, x1
+        umulh   x4, x9, x0
+        umulh   x5, x9, x1
+
+        adds    x3, x3, x4
+        adc     x4, x5, xzr
+        lsl     x5, x9, #60
+
+        subs    x10, x10, x2
+        sbcs    x11, x11, x3
+        sbcs    x12, x12, x4
+        sbcs    x13, x13, x5
+
+// If x' < 0 then just directly negate it; this makes sure the
+// reduced argument is strictly 0 <= x' < 2^252, but now we need
+// to record (done via bit 255 of the reduced scalar, which is
+// ignored in the main loop) when we negated so we can flip
+// the sign of the eventual point to compensate.
+
+        csetm   x9, cc
+        adds    xzr, x9, x9
+        eor     x10, x10, x9
+        adcs    x10, x10, xzr
+        eor     x11, x11, x9
+        adcs    x11, x11, xzr
+        eor     x12, x12, x9
+        adcs    x12, x12, xzr
+        eor     x13, x13, x9
+        adc     x13, x13, xzr
+
+        and     x9, x9, #0x8000000000000000
+        orr     x13, x13, x9
+
+// And before we store the scalar, test and reset bit 251 to
+// initialize the main loop just below.
+
+        stp     x10, x11, [scalar]
+        tst     x13, #0x0800000000000000
+        bic     x13, x13, #0x0800000000000000
+        stp     x12, x13, [scalar+16]
+
+// The main part of the computation is in extended-projective coordinates
+// (X,Y,Z,T), representing an affine point on the edwards25519 curve
+// (x,y) via x = X/Z, y = Y/Z and x * y = T/Z (so X * Y = T * Z).
+// In comments B means the standard basepoint (x,4/5) =
+// (0x216....f25d51a,0x6666..666658).
+//
+// Initialize accumulator "acc" to either 0 or 2^251 * B depending on
+// bit 251 of the (reduced) scalar. That leaves bits 0..250 to handle.
+
+#if defined(__ELF__)
+        adrp    tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant)
+        add     tab, tab, :lo12:S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant)
+#else
+        adrp    tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant)@PAGE
+        add     tab, tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant)@PAGEOFF
+#endif
+
+        ldp     x0, x1, [tab]
+        ldp     x2, x3, [tab, #96]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc]
+
+        ldp     x0, x1, [tab, #1*16]
+        ldp     x2, x3, [tab, #(96+1*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+1*16]
+
+        ldp     x0, x1, [tab, #2*16]
+        ldp     x2, x3, [tab, #(96+2*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+2*16]
+
+        ldp     x0, x1, [tab, #3*16]
+        ldp     x2, x3, [tab, #(96+3*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+3*16]
+
+        mov     x0, #1
+        stp     x0, xzr, [acc+4*16]
+        stp     xzr, xzr, [acc+5*16]
+
+        ldp     x0, x1, [tab, #4*16]
+        ldp     x2, x3, [tab, #(96+4*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+6*16]
+
+        ldp     x0, x1, [tab, #5*16]
+        ldp     x2, x3, [tab, #(96+5*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+7*16]
+
+// The counter "i" tracks the bit position for which the scalar has
+// already been absorbed, starting at 0 and going up in chunks of 4.
+//
+// The pointer "tab" points at the current block of the table for
+// multiples (2^i * j) * B at the current bit position i; 1 <= j <= 8.
+//
+// The bias is always either 0 and 1 and needs to be added to the
+// partially processed scalar implicitly. This is used to absorb 4 bits
+// of scalar per iteration from 3-bit table indexing by exploiting
+// negation: (16 * h + l) * B = (16 * (h + 1) - (16 - l)) * B is used
+// when l >= 9. Note that we can't have any bias left over at the
+// end because we made sure bit 251 is clear in the reduced scalar.
+
+        mov     i, 0
+        add     tab, tab, #192
+        mov     bias, xzr
+
+// Start of the main loop, repeated 63 times for i = 0, 4, 8, ..., 248
+
+Ledwards25519_scalarmulbase_scalarloop:
+
+// Look at the next 4-bit field "bf", adding the previous bias as well.
+// Choose the table index "ix" as bf when bf <= 8 and 16 - bf for bf >= 9,
+// setting the bias to 1 for the next iteration in the latter case.
+
+        lsr     x0, i, #6
+        ldr     x2, [sp, x0, lsl #3]    // Exploiting scalar = sp exactly
+        lsr     x2, x2, i
+        and     x2, x2, #15
+        add     bf, x2, bias
+
+        cmp     bf, 9
+        cset    bias, cs
+
+        mov     x0, 16
+        sub     x0, x0, bf
+        cmp     bias, xzr
+        csel    ix, x0, bf, ne
+
+// Perform constant-time lookup in the table to get element number "ix".
+// The table entry for the affine point (x,y) is actually a triple
+// (y - x,x + y,2 * d * x * y) to precompute parts of the addition.
+// Note that "ix" can be 0, so we set up the appropriate identity first.
+
+        mov     x0, #1
+        mov     x1, xzr
+        mov     x2, xzr
+        mov     x3, xzr
+        mov     x4, #1
+        mov     x5, xzr
+        mov     x6, xzr
+        mov     x7, xzr
+        mov     x8, xzr
+        mov     x9, xzr
+        mov     x10, xzr
+        mov     x11, xzr
+
+        cmp     ix, #1
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #2
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #3
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #4
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #5
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #6
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #7
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #8
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+// We now have the triple from the table in registers as follows
+//
+//      [x3;x2;x1;x0] = y - x
+//      [x7;x6;x5;x4] = x + y
+//      [x11;x10;x9;x8] = 2 * d * x * y
+//
+// In case bias = 1 we need to negate this. For Edwards curves
+// -(x,y) = (-x,y), i.e. we need to negate the x coordinate.
+// In this processed encoding, that amounts to swapping the
+// first two fields and negating the third.
+//
+// The optional negation here also pretends bias = 0 whenever
+// ix = 0 so that it doesn't need to handle the case of zero
+// inputs, since no non-trivial table entries are zero. Note
+// that in the zero case the whole negation is trivial, and
+// so indeed is the swapping.
+
+        cmp     bias, #0
+
+        csel    x12, x0, x4, eq
+        csel    x13, x1, x5, eq
+        csel    x14, x2, x6, eq
+        csel    x15, x3, x7, eq
+        stp     x12, x13, [tabent]
+        stp     x14, x15, [tabent+16]
+
+        csel    x12, x0, x4, ne
+        csel    x13, x1, x5, ne
+        csel    x14, x2, x6, ne
+        csel    x15, x3, x7, ne
+        stp     x12, x13, [tabent+32]
+        stp     x14, x15, [tabent+48]
+
+        mov     x0, #-19
+        subs    x0, x0, x8
+        mov     x2, #-1
+        sbcs    x1, x2, x9
+        sbcs    x2, x2, x10
+        mov     x3, #0x7FFFFFFFFFFFFFFF
+        sbc     x3, x3, x11
+
+        cmp     ix, xzr
+        ccmp    bias, xzr, #4, ne
+
+        csel    x0, x0, x8, ne
+        csel    x1, x1, x9, ne
+        stp     x0, x1, [tabent+64]
+        csel    x2, x2, x10, ne
+        csel    x3, x3, x11, ne
+        stp     x2, x3, [tabent+80]
+
+// Extended-projective and precomputed mixed addition.
+// This is effectively the same as calling the standalone
+// function edwards25519_pepadd_alt(acc,acc,tabent), but we
+// only retain slightly weaker normalization < 2 * p_25519
+// throughout the inner loop, so the computation is
+// slightly different, and faster overall.
+
+        double_twice4(t0,z_1)
+        sub_twice4(t1,y_1,x_1)
+        add_twice4(t2,y_1,x_1)
+        mul_4(t3,w_1,kxy_2)
+        mul_4(t1,t1,ymx_2)
+        mul_4(t2,t2,xpy_2)
+        sub_twice4(t4,t0,t3)
+        add_twice4(t0,t0,t3)
+        sub_twice4(t5,t2,t1)
+        add_twice4(t1,t2,t1)
+        mul_4(z_3,t4,t0)
+        mul_4(x_3,t5,t4)
+        mul_4(y_3,t0,t1)
+        mul_4(w_3,t5,t1)
+
+// End of the main loop; move on by 4 bits.
+
+        add     i, i, 4
+        cmp     i, 252
+        bcc     Ledwards25519_scalarmulbase_scalarloop
+
+// Insert the optional negation of the projective X coordinate, and
+// so by extension the final affine x coordinate x = X/Z and thus
+// the point P = (x,y). We only know X < 2 * p_25519, so we do the
+// negation as 2 * p_25519 - X to keep it nonnegative. From this
+// point on we don't need any normalization of the coordinates
+// except for making sure that they fit in 4 digits.
+
+        ldp     x0, x1, [x_3]
+        ldp     x2, x3, [x_3+16]
+        mov     x4, #0xffffffffffffffda
+        subs    x4, x4, x0
+        mov     x7, #0xffffffffffffffff
+        sbcs    x5, x7, x1
+        sbcs    x6, x7, x2
+        sbc     x7, x7, x3
+        ldr     x10, [scalar+24]
+        tst     x10, #0x8000000000000000
+        csel    x0, x4, x0, ne
+        csel    x1, x5, x1, ne
+        csel    x2, x6, x2, ne
+        csel    x3, x7, x3, ne
+        stp     x0, x1, [x_3]
+        stp     x2, x3, [x_3+16]
+
+// Now we need to map out of the extended-projective representation
+// (X,Y,Z,W) back to the affine form (x,y) = (X/Z,Y/Z). This means
+// first calling the modular inverse to get w_3 = 1/z_3.
+
+        add     x0, w_3
+        add     x1, z_3
+
+// Inline copy of bignum_inv_p25519, identical except for stripping out
+// the prologue and epilogue saving and restoring registers and making
+// and reclaiming room on the stack. For more details and explanations see
+// "arm/curve25519/bignum_inv_p25519.S". Note that the stack it uses for
+// its own temporaries is 128 bytes, so it has no effect on variables
+// that are needed in the rest of our computation here: res, w_3, x_3
+// and y_3.
+
+        mov     x20, x0
+        mov     x10, #0xffffffffffffffed
+        mov     x11, #0xffffffffffffffff
+        stp     x10, x11, [sp]
+        mov     x12, #0x7fffffffffffffff
+        stp     x11, x12, [sp, #16]
+        ldp     x2, x3, [x1]
+        ldp     x4, x5, [x1, #16]
+        mov     x7, #0x13
+        lsr     x6, x5, #63
+        madd    x6, x7, x6, x7
+        adds    x2, x2, x6
+        adcs    x3, x3, xzr
+        adcs    x4, x4, xzr
+        orr     x5, x5, #0x8000000000000000
+        adcs    x5, x5, xzr
+        csel    x6, x7, xzr, cc
+        subs    x2, x2, x6
+        sbcs    x3, x3, xzr
+        sbcs    x4, x4, xzr
+        sbc     x5, x5, xzr
+        and     x5, x5, #0x7fffffffffffffff
+        stp     x2, x3, [sp, #32]
+        stp     x4, x5, [sp, #48]
+        stp     xzr, xzr, [sp, #64]
+        stp     xzr, xzr, [sp, #80]
+        mov     x10, #0x2099
+        movk    x10, #0x7502, lsl #16
+        movk    x10, #0x9e23, lsl #32
+        movk    x10, #0xa0f9, lsl #48
+        mov     x11, #0x2595
+        movk    x11, #0x1d13, lsl #16
+        movk    x11, #0x8f3f, lsl #32
+        movk    x11, #0xa8c6, lsl #48
+        mov     x12, #0x5242
+        movk    x12, #0x5ac, lsl #16
+        movk    x12, #0x8938, lsl #32
+        movk    x12, #0x6c6c, lsl #48
+        mov     x13, #0x615
+        movk    x13, #0x4177, lsl #16
+        movk    x13, #0x8b2, lsl #32
+        movk    x13, #0x2765, lsl #48
+        stp     x10, x11, [sp, #96]
+        stp     x12, x13, [sp, #112]
+        mov     x21, #0xa
+        mov     x22, #0x1
+        b       Ledwards25519_scalarmulbase_invmidloop
+Ledwards25519_scalarmulbase_invloop:
+        cmp     x10, xzr
+        csetm   x14, mi
+        cneg    x10, x10, mi
+        cmp     x11, xzr
+        csetm   x15, mi
+        cneg    x11, x11, mi
+        cmp     x12, xzr
+        csetm   x16, mi
+        cneg    x12, x12, mi
+        cmp     x13, xzr
+        csetm   x17, mi
+        cneg    x13, x13, mi
+        and     x0, x10, x14
+        and     x1, x11, x15
+        add     x9, x0, x1
+        and     x0, x12, x16
+        and     x1, x13, x17
+        add     x19, x0, x1
+        ldr     x7, [sp]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #32]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        adc     x2, x2, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x5, x19, x0
+        adc     x3, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x7, [sp, #8]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #40]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        adc     x6, x6, x1
+        extr    x4, x2, x4, #59
+        str     x4, [sp]
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x3, x3, x0
+        adc     x4, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x3, x3, x0
+        adc     x4, x4, x1
+        extr    x5, x3, x5, #59
+        str     x5, [sp, #32]
+        ldr     x7, [sp, #16]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #48]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        adc     x5, x5, x1
+        extr    x2, x6, x2, #59
+        str     x2, [sp, #8]
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x4, x4, x0
+        adc     x2, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x4, x4, x0
+        adc     x2, x2, x1
+        extr    x3, x4, x3, #59
+        str     x3, [sp, #40]
+        ldr     x7, [sp, #24]
+        eor     x1, x7, x14
+        asr     x3, x1, #63
+        and     x3, x3, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #56]
+        eor     x1, x8, x15
+        asr     x0, x1, #63
+        and     x0, x0, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x5, x6, #59
+        str     x6, [sp, #16]
+        extr    x5, x3, x5, #59
+        str     x5, [sp, #24]
+        eor     x1, x7, x16
+        asr     x5, x1, #63
+        and     x5, x5, x12
+        neg     x5, x5
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        eor     x1, x8, x17
+        asr     x0, x1, #63
+        and     x0, x0, x13
+        sub     x5, x5, x0
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        extr    x4, x2, x4, #59
+        str     x4, [sp, #48]
+        extr    x2, x5, x2, #59
+        str     x2, [sp, #56]
+        ldr     x7, [sp, #64]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #96]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        str     x4, [sp, #64]
+        adc     x2, x2, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x5, x19, x0
+        adc     x3, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x5, x5, x0
+        str     x5, [sp, #96]
+        adc     x3, x3, x1
+        ldr     x7, [sp, #72]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #104]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        str     x2, [sp, #72]
+        adc     x6, x6, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x3, x3, x0
+        adc     x4, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x3, x3, x0
+        str     x3, [sp, #104]
+        adc     x4, x4, x1
+        ldr     x7, [sp, #80]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #112]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        str     x6, [sp, #80]
+        adc     x5, x5, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x4, x4, x0
+        adc     x2, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x4, x4, x0
+        str     x4, [sp, #112]
+        adc     x2, x2, x1
+        ldr     x7, [sp, #88]
+        eor     x1, x7, x14
+        and     x3, x14, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #120]
+        eor     x1, x8, x15
+        and     x0, x15, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x3, x5, #63
+        ldp     x0, x1, [sp, #64]
+        add     x6, x6, x3, asr #63
+        mov     x3, #0x13
+        mul     x4, x6, x3
+        add     x5, x5, x6, lsl #63
+        smulh   x3, x6, x3
+        ldr     x6, [sp, #80]
+        adds    x0, x0, x4
+        adcs    x1, x1, x3
+        asr     x3, x3, #63
+        adcs    x6, x6, x3
+        adc     x5, x5, x3
+        stp     x0, x1, [sp, #64]
+        stp     x6, x5, [sp, #80]
+        eor     x1, x7, x16
+        and     x5, x16, x12
+        neg     x5, x5
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        eor     x1, x8, x17
+        and     x0, x17, x13
+        sub     x5, x5, x0
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        extr    x6, x5, x2, #63
+        ldp     x0, x1, [sp, #96]
+        add     x6, x6, x5, asr #63
+        mov     x5, #0x13
+        mul     x4, x6, x5
+        add     x2, x2, x6, lsl #63
+        smulh   x5, x6, x5
+        ldr     x3, [sp, #112]
+        adds    x0, x0, x4
+        adcs    x1, x1, x5
+        asr     x5, x5, #63
+        adcs    x3, x3, x5
+        adc     x2, x2, x5
+        stp     x0, x1, [sp, #96]
+        stp     x3, x2, [sp, #112]
+Ledwards25519_scalarmulbase_invmidloop:
+        mov     x1, x22
+        ldr     x2, [sp]
+        ldr     x3, [sp, #32]
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x8, x4, #0x100, lsl #12
+        sbfx    x8, x8, #21, #21
+        mov     x11, #0x100000
+        add     x11, x11, x11, lsl #21
+        add     x9, x4, x11
+        asr     x9, x9, #42
+        add     x10, x5, #0x100, lsl #12
+        sbfx    x10, x10, #21, #21
+        add     x11, x5, x11
+        asr     x11, x11, #42
+        mul     x6, x8, x2
+        mul     x7, x9, x3
+        mul     x2, x10, x2
+        mul     x3, x11, x3
+        add     x4, x6, x7
+        add     x5, x2, x3
+        asr     x2, x4, #20
+        asr     x3, x5, #20
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x12, x4, #0x100, lsl #12
+        sbfx    x12, x12, #21, #21
+        mov     x15, #0x100000
+        add     x15, x15, x15, lsl #21
+        add     x13, x4, x15
+        asr     x13, x13, #42
+        add     x14, x5, #0x100, lsl #12
+        sbfx    x14, x14, #21, #21
+        add     x15, x5, x15
+        asr     x15, x15, #42
+        mul     x6, x12, x2
+        mul     x7, x13, x3
+        mul     x2, x14, x2
+        mul     x3, x15, x3
+        add     x4, x6, x7
+        add     x5, x2, x3
+        asr     x2, x4, #20
+        asr     x3, x5, #20
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        mul     x2, x12, x8
+        mul     x3, x12, x9
+        mul     x6, x14, x8
+        mul     x7, x14, x9
+        madd    x8, x13, x10, x2
+        madd    x9, x13, x11, x3
+        madd    x16, x15, x10, x6
+        madd    x17, x15, x11, x7
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x12, x4, #0x100, lsl #12
+        sbfx    x12, x12, #22, #21
+        mov     x15, #0x100000
+        add     x15, x15, x15, lsl #21
+        add     x13, x4, x15
+        asr     x13, x13, #43
+        add     x14, x5, #0x100, lsl #12
+        sbfx    x14, x14, #22, #21
+        add     x15, x5, x15
+        asr     x15, x15, #43
+        mneg    x2, x12, x8
+        mneg    x3, x12, x9
+        mneg    x4, x14, x8
+        mneg    x5, x14, x9
+        msub    x10, x13, x16, x2
+        msub    x11, x13, x17, x3
+        msub    x12, x15, x16, x4
+        msub    x13, x15, x17, x5
+        mov     x22, x1
+        subs    x21, x21, #0x1
+        b.ne    Ledwards25519_scalarmulbase_invloop
+        ldr     x0, [sp]
+        ldr     x1, [sp, #32]
+        mul     x0, x0, x10
+        madd    x1, x1, x11, x0
+        asr     x0, x1, #63
+        cmp     x10, xzr
+        csetm   x14, mi
+        cneg    x10, x10, mi
+        eor     x14, x14, x0
+        cmp     x11, xzr
+        csetm   x15, mi
+        cneg    x11, x11, mi
+        eor     x15, x15, x0
+        cmp     x12, xzr
+        csetm   x16, mi
+        cneg    x12, x12, mi
+        eor     x16, x16, x0
+        cmp     x13, xzr
+        csetm   x17, mi
+        cneg    x13, x13, mi
+        eor     x17, x17, x0
+        and     x0, x10, x14
+        and     x1, x11, x15
+        add     x9, x0, x1
+        ldr     x7, [sp, #64]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #96]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        str     x4, [sp, #64]
+        adc     x2, x2, x1
+        ldr     x7, [sp, #72]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #104]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        str     x2, [sp, #72]
+        adc     x6, x6, x1
+        ldr     x7, [sp, #80]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #112]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        str     x6, [sp, #80]
+        adc     x5, x5, x1
+        ldr     x7, [sp, #88]
+        eor     x1, x7, x14
+        and     x3, x14, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #120]
+        eor     x1, x8, x15
+        and     x0, x15, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x3, x5, #63
+        ldp     x0, x1, [sp, #64]
+        tst     x3, x3
+        cinc    x6, x6, pl
+        mov     x3, #0x13
+        mul     x4, x6, x3
+        add     x5, x5, x6, lsl #63
+        smulh   x6, x6, x3
+        ldr     x2, [sp, #80]
+        adds    x0, x0, x4
+        adcs    x1, x1, x6
+        asr     x6, x6, #63
+        adcs    x2, x2, x6
+        adcs    x5, x5, x6
+        csel    x3, x3, xzr, mi
+        subs    x0, x0, x3
+        sbcs    x1, x1, xzr
+        sbcs    x2, x2, xzr
+        sbc     x5, x5, xzr
+        and     x5, x5, #0x7fffffffffffffff
+        mov     x4, x20
+        stp     x0, x1, [x4]
+        stp     x2, x5, [x4, #16]
+
+// The final result is x = X * inv(Z), y = Y * inv(Z).
+// These are the only operations in the whole computation that
+// fully reduce modulo p_25519 since now we want the canonical
+// answer as output.
+
+        mul_p25519(resx,x_3,w_3)
+        mul_p25519(resy,y_3,w_3)
+
+// Restore stack and registers
+
+        CFI_INC_SP(NSPACE)
+        CFI_POP2(x23,x24)
+        CFI_POP2(x21,x22)
+        CFI_POP2(x19,x20)
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
+
+// ****************************************************************************
+// The precomputed data (all read-only).
+// ****************************************************************************
+
+#if defined(__ELF__)
+.section .rodata
+.type S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant), %object
+.size S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant), 48576
+#elif defined(__APPLE__)
+.const_data
+#endif
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant):
+
+// 0 * B = 0 and 2^251 * B in extended-projective coordinates
+// but with Z = 1 assumed and hence left out, so they are (X,Y,T) only.
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000001
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x525f946d7c7220e7
+        .quad   0x4636b0b2f1e35444
+        .quad   0x796e9d70e892ae0f
+        .quad   0x03dec05fa937adb1
+        .quad   0x6d1c271cc6375515
+        .quad   0x462588c4a4ca4f14
+        .quad   0x691129fee55afc39
+        .quad   0x15949f784d8472f5
+        .quad   0xbd89e510afad0049
+        .quad   0x4d1f08c073b9860e
+        .quad   0x07716e8b2d00af9d
+        .quad   0x70d685f68f859714
+
+// Precomputed table of multiples of generator for edwards25519
+// all in precomputed extended-projective (y-x,x+y,2*d*x*y) triples.
+
+        // 2^0 * 1 * G
+
+        .quad   0x9d103905d740913e
+        .quad   0xfd399f05d140beb3
+        .quad   0xa5c18434688f8a09
+        .quad   0x44fd2f9298f81267
+        .quad   0x2fbc93c6f58c3b85
+        .quad   0xcf932dc6fb8c0e19
+        .quad   0x270b4898643d42c2
+        .quad   0x07cf9d3a33d4ba65
+        .quad   0xabc91205877aaa68
+        .quad   0x26d9e823ccaac49e
+        .quad   0x5a1b7dcbdd43598c
+        .quad   0x6f117b689f0c65a8
+
+        // 2^0 * 2 * G
+
+        .quad   0x8a99a56042b4d5a8
+        .quad   0x8f2b810c4e60acf6
+        .quad   0xe09e236bb16e37aa
+        .quad   0x6bb595a669c92555
+        .quad   0x9224e7fc933c71d7
+        .quad   0x9f469d967a0ff5b5
+        .quad   0x5aa69a65e1d60702
+        .quad   0x590c063fa87d2e2e
+        .quad   0x43faa8b3a59b7a5f
+        .quad   0x36c16bdd5d9acf78
+        .quad   0x500fa0840b3d6a31
+        .quad   0x701af5b13ea50b73
+
+        // 2^0 * 3 * G
+
+        .quad   0x56611fe8a4fcd265
+        .quad   0x3bd353fde5c1ba7d
+        .quad   0x8131f31a214bd6bd
+        .quad   0x2ab91587555bda62
+        .quad   0xaf25b0a84cee9730
+        .quad   0x025a8430e8864b8a
+        .quad   0xc11b50029f016732
+        .quad   0x7a164e1b9a80f8f4
+        .quad   0x14ae933f0dd0d889
+        .quad   0x589423221c35da62
+        .quad   0xd170e5458cf2db4c
+        .quad   0x5a2826af12b9b4c6
+
+        // 2^0 * 4 * G
+
+        .quad   0x95fe050a056818bf
+        .quad   0x327e89715660faa9
+        .quad   0xc3e8e3cd06a05073
+        .quad   0x27933f4c7445a49a
+        .quad   0x287351b98efc099f
+        .quad   0x6765c6f47dfd2538
+        .quad   0xca348d3dfb0a9265
+        .quad   0x680e910321e58727
+        .quad   0x5a13fbe9c476ff09
+        .quad   0x6e9e39457b5cc172
+        .quad   0x5ddbdcf9102b4494
+        .quad   0x7f9d0cbf63553e2b
+
+        // 2^0 * 5 * G
+
+        .quad   0x7f9182c3a447d6ba
+        .quad   0xd50014d14b2729b7
+        .quad   0xe33cf11cb864a087
+        .quad   0x154a7e73eb1b55f3
+        .quad   0xa212bc4408a5bb33
+        .quad   0x8d5048c3c75eed02
+        .quad   0xdd1beb0c5abfec44
+        .quad   0x2945ccf146e206eb
+        .quad   0xbcbbdbf1812a8285
+        .quad   0x270e0807d0bdd1fc
+        .quad   0xb41b670b1bbda72d
+        .quad   0x43aabe696b3bb69a
+
+        // 2^0 * 6 * G
+
+        .quad   0x499806b67b7d8ca4
+        .quad   0x575be28427d22739
+        .quad   0xbb085ce7204553b9
+        .quad   0x38b64c41ae417884
+        .quad   0x3a0ceeeb77157131
+        .quad   0x9b27158900c8af88
+        .quad   0x8065b668da59a736
+        .quad   0x51e57bb6a2cc38bd
+        .quad   0x85ac326702ea4b71
+        .quad   0xbe70e00341a1bb01
+        .quad   0x53e4a24b083bc144
+        .quad   0x10b8e91a9f0d61e3
+
+        // 2^0 * 7 * G
+
+        .quad   0xba6f2c9aaa3221b1
+        .quad   0x6ca021533bba23a7
+        .quad   0x9dea764f92192c3a
+        .quad   0x1d6edd5d2e5317e0
+        .quad   0x6b1a5cd0944ea3bf
+        .quad   0x7470353ab39dc0d2
+        .quad   0x71b2528228542e49
+        .quad   0x461bea69283c927e
+        .quad   0xf1836dc801b8b3a2
+        .quad   0xb3035f47053ea49a
+        .quad   0x529c41ba5877adf3
+        .quad   0x7a9fbb1c6a0f90a7
+
+        // 2^0 * 8 * G
+
+        .quad   0xe2a75dedf39234d9
+        .quad   0x963d7680e1b558f9
+        .quad   0x2c2741ac6e3c23fb
+        .quad   0x3a9024a1320e01c3
+        .quad   0x59b7596604dd3e8f
+        .quad   0x6cb30377e288702c
+        .quad   0xb1339c665ed9c323
+        .quad   0x0915e76061bce52f
+        .quad   0xe7c1f5d9c9a2911a
+        .quad   0xb8a371788bcca7d7
+        .quad   0x636412190eb62a32
+        .quad   0x26907c5c2ecc4e95
+
+        // 2^4 * 1 * B
+
+        .quad   0x7ec851ca553e2df3
+        .quad   0xa71284cba64878b3
+        .quad   0xe6b5e4193288d1e7
+        .quad   0x4cf210ec5a9a8883
+        .quad   0x322d04a52d9021f6
+        .quad   0xb9c19f3375c6bf9c
+        .quad   0x587a3a4342d20b09
+        .quad   0x143b1cf8aa64fe61
+        .quad   0x9f867c7d968acaab
+        .quad   0x5f54258e27092729
+        .quad   0xd0a7d34bea180975
+        .quad   0x21b546a3374126e1
+
+        // 2^4 * 2 * B
+
+        .quad   0xa94ff858a2888343
+        .quad   0xce0ed4565313ed3c
+        .quad   0xf55c3dcfb5bf34fa
+        .quad   0x0a653ca5c9eab371
+        .quad   0x490a7a45d185218f
+        .quad   0x9a15377846049335
+        .quad   0x0060ea09cc31e1f6
+        .quad   0x7e041577f86ee965
+        .quad   0x66b2a496ce5b67f3
+        .quad   0xff5492d8bd569796
+        .quad   0x503cec294a592cd0
+        .quad   0x566943650813acb2
+
+        // 2^4 * 3 * B
+
+        .quad   0xb818db0c26620798
+        .quad   0x5d5c31d9606e354a
+        .quad   0x0982fa4f00a8cdc7
+        .quad   0x17e12bcd4653e2d4
+        .quad   0x5672f9eb1dabb69d
+        .quad   0xba70b535afe853fc
+        .quad   0x47ac0f752796d66d
+        .quad   0x32a5351794117275
+        .quad   0xd3a644a6df648437
+        .quad   0x703b6559880fbfdd
+        .quad   0xcb852540ad3a1aa5
+        .quad   0x0900b3f78e4c6468
+
+        // 2^4 * 4 * B
+
+        .quad   0x0a851b9f679d651b
+        .quad   0xe108cb61033342f2
+        .quad   0xd601f57fe88b30a3
+        .quad   0x371f3acaed2dd714
+        .quad   0xed280fbec816ad31
+        .quad   0x52d9595bd8e6efe3
+        .quad   0x0fe71772f6c623f5
+        .quad   0x4314030b051e293c
+        .quad   0xd560005efbf0bcad
+        .quad   0x8eb70f2ed1870c5e
+        .quad   0x201f9033d084e6a0
+        .quad   0x4c3a5ae1ce7b6670
+
+        // 2^4 * 5 * B
+
+        .quad   0x4138a434dcb8fa95
+        .quad   0x870cf67d6c96840b
+        .quad   0xde388574297be82c
+        .quad   0x7c814db27262a55a
+        .quad   0xbaf875e4c93da0dd
+        .quad   0xb93282a771b9294d
+        .quad   0x80d63fb7f4c6c460
+        .quad   0x6de9c73dea66c181
+        .quad   0x478904d5a04df8f2
+        .quad   0xfafbae4ab10142d3
+        .quad   0xf6c8ac63555d0998
+        .quad   0x5aac4a412f90b104
+
+        // 2^4 * 6 * B
+
+        .quad   0xc64f326b3ac92908
+        .quad   0x5551b282e663e1e0
+        .quad   0x476b35f54a1a4b83
+        .quad   0x1b9da3fe189f68c2
+        .quad   0x603a0d0abd7f5134
+        .quad   0x8089c932e1d3ae46
+        .quad   0xdf2591398798bd63
+        .quad   0x1c145cd274ba0235
+        .quad   0x32e8386475f3d743
+        .quad   0x365b8baf6ae5d9ef
+        .quad   0x825238b6385b681e
+        .quad   0x234929c1167d65e1
+
+        // 2^4 * 7 * B
+
+        .quad   0x984decaba077ade8
+        .quad   0x383f77ad19eb389d
+        .quad   0xc7ec6b7e2954d794
+        .quad   0x59c77b3aeb7c3a7a
+        .quad   0x48145cc21d099fcf
+        .quad   0x4535c192cc28d7e5
+        .quad   0x80e7c1e548247e01
+        .quad   0x4a5f28743b2973ee
+        .quad   0xd3add725225ccf62
+        .quad   0x911a3381b2152c5d
+        .quad   0xd8b39fad5b08f87d
+        .quad   0x6f05606b4799fe3b
+
+        // 2^4 * 8 * B
+
+        .quad   0x9ffe9e92177ba962
+        .quad   0x98aee71d0de5cae1
+        .quad   0x3ff4ae942d831044
+        .quad   0x714de12e58533ac8
+        .quad   0x5b433149f91b6483
+        .quad   0xadb5dc655a2cbf62
+        .quad   0x87fa8412632827b3
+        .quad   0x60895e91ab49f8d8
+        .quad   0xe9ecf2ed0cf86c18
+        .quad   0xb46d06120735dfd4
+        .quad   0xbc9da09804b96be7
+        .quad   0x73e2e62fd96dc26b
+
+        // 2^8 * 1 * B
+
+        .quad   0xed5b635449aa515e
+        .quad   0xa865c49f0bc6823a
+        .quad   0x850c1fe95b42d1c4
+        .quad   0x30d76d6f03d315b9
+        .quad   0x2eccdd0e632f9c1d
+        .quad   0x51d0b69676893115
+        .quad   0x52dfb76ba8637a58
+        .quad   0x6dd37d49a00eef39
+        .quad   0x6c4444172106e4c7
+        .quad   0xfb53d680928d7f69
+        .quad   0xb4739ea4694d3f26
+        .quad   0x10c697112e864bb0
+
+        // 2^8 * 2 * B
+
+        .quad   0x6493c4277dbe5fde
+        .quad   0x265d4fad19ad7ea2
+        .quad   0x0e00dfc846304590
+        .quad   0x25e61cabed66fe09
+        .quad   0x0ca62aa08358c805
+        .quad   0x6a3d4ae37a204247
+        .quad   0x7464d3a63b11eddc
+        .quad   0x03bf9baf550806ef
+        .quad   0x3f13e128cc586604
+        .quad   0x6f5873ecb459747e
+        .quad   0xa0b63dedcc1268f5
+        .quad   0x566d78634586e22c
+
+        // 2^8 * 3 * B
+
+        .quad   0x1637a49f9cc10834
+        .quad   0xbc8e56d5a89bc451
+        .quad   0x1cb5ec0f7f7fd2db
+        .quad   0x33975bca5ecc35d9
+        .quad   0xa1054285c65a2fd0
+        .quad   0x6c64112af31667c3
+        .quad   0x680ae240731aee58
+        .quad   0x14fba5f34793b22a
+        .quad   0x3cd746166985f7d4
+        .quad   0x593e5e84c9c80057
+        .quad   0x2fc3f2b67b61131e
+        .quad   0x14829cea83fc526c
+
+        // 2^8 * 4 * B
+
+        .quad   0xff437b8497dd95c2
+        .quad   0x6c744e30aa4eb5a7
+        .quad   0x9e0c5d613c85e88b
+        .quad   0x2fd9c71e5f758173
+        .quad   0x21e70b2f4e71ecb8
+        .quad   0xe656ddb940a477e3
+        .quad   0xbf6556cece1d4f80
+        .quad   0x05fc3bc4535d7b7e
+        .quad   0x24b8b3ae52afdedd
+        .quad   0x3495638ced3b30cf
+        .quad   0x33a4bc83a9be8195
+        .quad   0x373767475c651f04
+
+        // 2^8 * 5 * B
+
+        .quad   0x2fba99fd40d1add9
+        .quad   0xb307166f96f4d027
+        .quad   0x4363f05215f03bae
+        .quad   0x1fbea56c3b18f999
+        .quad   0x634095cb14246590
+        .quad   0xef12144016c15535
+        .quad   0x9e38140c8910bc60
+        .quad   0x6bf5905730907c8c
+        .quad   0x0fa778f1e1415b8a
+        .quad   0x06409ff7bac3a77e
+        .quad   0x6f52d7b89aa29a50
+        .quad   0x02521cf67a635a56
+
+        // 2^8 * 6 * B
+
+        .quad   0x513fee0b0a9d5294
+        .quad   0x8f98e75c0fdf5a66
+        .quad   0xd4618688bfe107ce
+        .quad   0x3fa00a7e71382ced
+        .quad   0xb1146720772f5ee4
+        .quad   0xe8f894b196079ace
+        .quad   0x4af8224d00ac824a
+        .quad   0x001753d9f7cd6cc4
+        .quad   0x3c69232d963ddb34
+        .quad   0x1dde87dab4973858
+        .quad   0xaad7d1f9a091f285
+        .quad   0x12b5fe2fa048edb6
+
+        // 2^8 * 7 * B
+
+        .quad   0x71f0fbc496fce34d
+        .quad   0x73b9826badf35bed
+        .quad   0xd2047261ff28c561
+        .quad   0x749b76f96fb1206f
+        .quad   0xdf2b7c26ad6f1e92
+        .quad   0x4b66d323504b8913
+        .quad   0x8c409dc0751c8bc3
+        .quad   0x6f7e93c20796c7b8
+        .quad   0x1f5af604aea6ae05
+        .quad   0xc12351f1bee49c99
+        .quad   0x61a808b5eeff6b66
+        .quad   0x0fcec10f01e02151
+
+        // 2^8 * 8 * B
+
+        .quad   0x644d58a649fe1e44
+        .quad   0x21fcaea231ad777e
+        .quad   0x02441c5a887fd0d2
+        .quad   0x4901aa7183c511f3
+        .quad   0x3df2d29dc4244e45
+        .quad   0x2b020e7493d8de0a
+        .quad   0x6cc8067e820c214d
+        .quad   0x413779166feab90a
+        .quad   0x08b1b7548c1af8f0
+        .quad   0xce0f7a7c246299b4
+        .quad   0xf760b0f91e06d939
+        .quad   0x41bb887b726d1213
+
+        // 2^12 * 1 * B
+
+        .quad   0x9267806c567c49d8
+        .quad   0x066d04ccca791e6a
+        .quad   0xa69f5645e3cc394b
+        .quad   0x5c95b686a0788cd2
+        .quad   0x97d980e0aa39f7d2
+        .quad   0x35d0384252c6b51c
+        .quad   0x7d43f49307cd55aa
+        .quad   0x56bd36cfb78ac362
+        .quad   0x2ac519c10d14a954
+        .quad   0xeaf474b494b5fa90
+        .quad   0xe6af8382a9f87a5a
+        .quad   0x0dea6db1879be094
+
+        // 2^12 * 2 * B
+
+        .quad   0xaa66bf547344e5ab
+        .quad   0xda1258888f1b4309
+        .quad   0x5e87d2b3fd564b2f
+        .quad   0x5b2c78885483b1dd
+        .quad   0x15baeb74d6a8797a
+        .quad   0x7ef55cf1fac41732
+        .quad   0x29001f5a3c8b05c5
+        .quad   0x0ad7cc8752eaccfb
+        .quad   0x52151362793408cf
+        .quad   0xeb0f170319963d94
+        .quad   0xa833b2fa883d9466
+        .quad   0x093a7fa775003c78
+
+        // 2^12 * 3 * B
+
+        .quad   0xe5107de63a16d7be
+        .quad   0xa377ffdc9af332cf
+        .quad   0x70d5bf18440b677f
+        .quad   0x6a252b19a4a31403
+        .quad   0xb8e9604460a91286
+        .quad   0x7f3fd8047778d3de
+        .quad   0x67d01e31bf8a5e2d
+        .quad   0x7b038a06c27b653e
+        .quad   0x9ed919d5d36990f3
+        .quad   0x5213aebbdb4eb9f2
+        .quad   0xc708ea054cb99135
+        .quad   0x58ded57f72260e56
+
+        // 2^12 * 4 * B
+
+        .quad   0x78e79dade9413d77
+        .quad   0xf257f9d59729e67d
+        .quad   0x59db910ee37aa7e6
+        .quad   0x6aa11b5bbb9e039c
+        .quad   0xda6d53265b0fd48b
+        .quad   0x8960823193bfa988
+        .quad   0xd78ac93261d57e28
+        .quad   0x79f2942d3a5c8143
+        .quad   0x97da2f25b6c88de9
+        .quad   0x251ba7eaacf20169
+        .quad   0x09b44f87ef4eb4e4
+        .quad   0x7d90ab1bbc6a7da5
+
+        // 2^12 * 5 * B
+
+        .quad   0x9acca683a7016bfe
+        .quad   0x90505f4df2c50b6d
+        .quad   0x6b610d5fcce435aa
+        .quad   0x19a10d446198ff96
+        .quad   0x1a07a3f496b3c397
+        .quad   0x11ceaa188f4e2532
+        .quad   0x7d9498d5a7751bf0
+        .quad   0x19ed161f508dd8a0
+        .quad   0x560a2cd687dce6ca
+        .quad   0x7f3568c48664cf4d
+        .quad   0x8741e95222803a38
+        .quad   0x483bdab1595653fc
+
+        // 2^12 * 6 * B
+
+        .quad   0xfa780f148734fa49
+        .quad   0x106f0b70360534e0
+        .quad   0x2210776fe3e307bd
+        .quad   0x3286c109dde6a0fe
+        .quad   0xd6cf4d0ab4da80f6
+        .quad   0x82483e45f8307fe0
+        .quad   0x05005269ae6f9da4
+        .quad   0x1c7052909cf7877a
+        .quad   0x32ee7de2874e98d4
+        .quad   0x14c362e9b97e0c60
+        .quad   0x5781dcde6a60a38a
+        .quad   0x217dd5eaaa7aa840
+
+        // 2^12 * 7 * B
+
+        .quad   0x9db7c4d0248e1eb0
+        .quad   0xe07697e14d74bf52
+        .quad   0x1e6a9b173c562354
+        .quad   0x7fa7c21f795a4965
+        .quad   0x8bdf1fb9be8c0ec8
+        .quad   0x00bae7f8e30a0282
+        .quad   0x4963991dad6c4f6c
+        .quad   0x07058a6e5df6f60a
+        .quad   0xe9eb02c4db31f67f
+        .quad   0xed25fd8910bcfb2b
+        .quad   0x46c8131f5c5cddb4
+        .quad   0x33b21c13a0cb9bce
+
+        // 2^12 * 8 * B
+
+        .quad   0x360692f8087d8e31
+        .quad   0xf4dcc637d27163f7
+        .quad   0x25a4e62065ea5963
+        .quad   0x659bf72e5ac160d9
+        .quad   0x9aafb9b05ee38c5b
+        .quad   0xbf9d2d4e071a13c7
+        .quad   0x8eee6e6de933290a
+        .quad   0x1c3bab17ae109717
+        .quad   0x1c9ab216c7cab7b0
+        .quad   0x7d65d37407bbc3cc
+        .quad   0x52744750504a58d5
+        .quad   0x09f2606b131a2990
+
+        // 2^16 * 1 * B
+
+        .quad   0x40e87d44744346be
+        .quad   0x1d48dad415b52b25
+        .quad   0x7c3a8a18a13b603e
+        .quad   0x4eb728c12fcdbdf7
+        .quad   0x7e234c597c6691ae
+        .quad   0x64889d3d0a85b4c8
+        .quad   0xdae2c90c354afae7
+        .quad   0x0a871e070c6a9e1d
+        .quad   0x3301b5994bbc8989
+        .quad   0x736bae3a5bdd4260
+        .quad   0x0d61ade219d59e3c
+        .quad   0x3ee7300f2685d464
+
+        // 2^16 * 2 * B
+
+        .quad   0xf5d255e49e7dd6b7
+        .quad   0x8016115c610b1eac
+        .quad   0x3c99975d92e187ca
+        .quad   0x13815762979125c2
+        .quad   0x43fa7947841e7518
+        .quad   0xe5c6fa59639c46d7
+        .quad   0xa1065e1de3052b74
+        .quad   0x7d47c6a2cfb89030
+        .quad   0x3fdad0148ef0d6e0
+        .quad   0x9d3e749a91546f3c
+        .quad   0x71ec621026bb8157
+        .quad   0x148cf58d34c9ec80
+
+        // 2^16 * 3 * B
+
+        .quad   0x46a492f67934f027
+        .quad   0x469984bef6840aa9
+        .quad   0x5ca1bc2a89611854
+        .quad   0x3ff2fa1ebd5dbbd4
+        .quad   0xe2572f7d9ae4756d
+        .quad   0x56c345bb88f3487f
+        .quad   0x9fd10b6d6960a88d
+        .quad   0x278febad4eaea1b9
+        .quad   0xb1aa681f8c933966
+        .quad   0x8c21949c20290c98
+        .quad   0x39115291219d3c52
+        .quad   0x4104dd02fe9c677b
+
+        // 2^16 * 4 * B
+
+        .quad   0x72b2bf5e1124422a
+        .quad   0xa1fa0c3398a33ab5
+        .quad   0x94cb6101fa52b666
+        .quad   0x2c863b00afaf53d5
+        .quad   0x81214e06db096ab8
+        .quad   0x21a8b6c90ce44f35
+        .quad   0x6524c12a409e2af5
+        .quad   0x0165b5a48efca481
+        .quad   0xf190a474a0846a76
+        .quad   0x12eff984cd2f7cc0
+        .quad   0x695e290658aa2b8f
+        .quad   0x591b67d9bffec8b8
+
+        // 2^16 * 5 * B
+
+        .quad   0x312f0d1c80b49bfa
+        .quad   0x5979515eabf3ec8a
+        .quad   0x727033c09ef01c88
+        .quad   0x3de02ec7ca8f7bcb
+        .quad   0x99b9b3719f18b55d
+        .quad   0xe465e5faa18c641e
+        .quad   0x61081136c29f05ed
+        .quad   0x489b4f867030128b
+        .quad   0xd232102d3aeb92ef
+        .quad   0xe16253b46116a861
+        .quad   0x3d7eabe7190baa24
+        .quad   0x49f5fbba496cbebf
+
+        // 2^16 * 6 * B
+
+        .quad   0x30949a108a5bcfd4
+        .quad   0xdc40dd70bc6473eb
+        .quad   0x92c294c1307c0d1c
+        .quad   0x5604a86dcbfa6e74
+        .quad   0x155d628c1e9c572e
+        .quad   0x8a4d86acc5884741
+        .quad   0x91a352f6515763eb
+        .quad   0x06a1a6c28867515b
+        .quad   0x7288d1d47c1764b6
+        .quad   0x72541140e0418b51
+        .quad   0x9f031a6018acf6d1
+        .quad   0x20989e89fe2742c6
+
+        // 2^16 * 7 * B
+
+        .quad   0x499777fd3a2dcc7f
+        .quad   0x32857c2ca54fd892
+        .quad   0xa279d864d207e3a0
+        .quad   0x0403ed1d0ca67e29
+        .quad   0x1674278b85eaec2e
+        .quad   0x5621dc077acb2bdf
+        .quad   0x640a4c1661cbf45a
+        .quad   0x730b9950f70595d3
+        .quad   0xc94b2d35874ec552
+        .quad   0xc5e6c8cf98246f8d
+        .quad   0xf7cb46fa16c035ce
+        .quad   0x5bd7454308303dcc
+
+        // 2^16 * 8 * B
+
+        .quad   0x7f9ad19528b24cc2
+        .quad   0x7f6b54656335c181
+        .quad   0x66b8b66e4fc07236
+        .quad   0x133a78007380ad83
+        .quad   0x85c4932115e7792a
+        .quad   0xc64c89a2bdcdddc9
+        .quad   0x9d1e3da8ada3d762
+        .quad   0x5bb7db123067f82c
+        .quad   0x0961f467c6ca62be
+        .quad   0x04ec21d6211952ee
+        .quad   0x182360779bd54770
+        .quad   0x740dca6d58f0e0d2
+
+        // 2^20 * 1 * B
+
+        .quad   0x50b70bf5d3f0af0b
+        .quad   0x4feaf48ae32e71f7
+        .quad   0x60e84ed3a55bbd34
+        .quad   0x00ed489b3f50d1ed
+        .quad   0x3906c72aed261ae5
+        .quad   0x9ab68fd988e100f7
+        .quad   0xf5e9059af3360197
+        .quad   0x0e53dc78bf2b6d47
+        .quad   0xb90829bf7971877a
+        .quad   0x5e4444636d17e631
+        .quad   0x4d05c52e18276893
+        .quad   0x27632d9a5a4a4af5
+
+        // 2^20 * 2 * B
+
+        .quad   0xd11ff05154b260ce
+        .quad   0xd86dc38e72f95270
+        .quad   0x601fcd0d267cc138
+        .quad   0x2b67916429e90ccd
+        .quad   0xa98285d187eaffdb
+        .quad   0xa5b4fbbbd8d0a864
+        .quad   0xb658f27f022663f7
+        .quad   0x3bbc2b22d99ce282
+        .quad   0xb917c952583c0a58
+        .quad   0x653ff9b80fe4c6f3
+        .quad   0x9b0da7d7bcdf3c0c
+        .quad   0x43a0eeb6ab54d60e
+
+        // 2^20 * 3 * B
+
+        .quad   0x396966a46d4a5487
+        .quad   0xf811a18aac2bb3ba
+        .quad   0x66e4685b5628b26b
+        .quad   0x70a477029d929b92
+        .quad   0x3ac6322357875fe8
+        .quad   0xd9d4f4ecf5fbcb8f
+        .quad   0x8dee8493382bb620
+        .quad   0x50c5eaa14c799fdc
+        .quad   0xdd0edc8bd6f2fb3c
+        .quad   0x54c63aa79cc7b7a0
+        .quad   0xae0b032b2c8d9f1a
+        .quad   0x6f9ce107602967fb
+
+        // 2^20 * 4 * B
+
+        .quad   0xad1054b1cde1c22a
+        .quad   0xc4a8e90248eb32df
+        .quad   0x5f3e7b33accdc0ea
+        .quad   0x72364713fc79963e
+        .quad   0x139693063520e0b5
+        .quad   0x437fcf7c88ea03fe
+        .quad   0xf7d4c40bd3c959bc
+        .quad   0x699154d1f893ded9
+        .quad   0x315d5c75b4b27526
+        .quad   0xcccb842d0236daa5
+        .quad   0x22f0c8a3345fee8e
+        .quad   0x73975a617d39dbed
+
+        // 2^20 * 5 * B
+
+        .quad   0xe4024df96375da10
+        .quad   0x78d3251a1830c870
+        .quad   0x902b1948658cd91c
+        .quad   0x7e18b10b29b7438a
+        .quad   0x6f37f392f4433e46
+        .quad   0x0e19b9a11f566b18
+        .quad   0x220fb78a1fd1d662
+        .quad   0x362a4258a381c94d
+        .quad   0x9071d9132b6beb2f
+        .quad   0x0f26e9ad28418247
+        .quad   0xeab91ec9bdec925d
+        .quad   0x4be65bc8f48af2de
+
+        // 2^20 * 6 * B
+
+        .quad   0x78487feba36e7028
+        .quad   0x5f3f13001dd8ce34
+        .quad   0x934fb12d4b30c489
+        .quad   0x056c244d397f0a2b
+        .quad   0x1d50fba257c26234
+        .quad   0x7bd4823adeb0678b
+        .quad   0xc2b0dc6ea6538af5
+        .quad   0x5665eec6351da73e
+        .quad   0xdb3ee00943bfb210
+        .quad   0x4972018720800ac2
+        .quad   0x26ab5d6173bd8667
+        .quad   0x20b209c2ab204938
+
+        // 2^20 * 7 * B
+
+        .quad   0x549e342ac07fb34b
+        .quad   0x02d8220821373d93
+        .quad   0xbc262d70acd1f567
+        .quad   0x7a92c9fdfbcac784
+        .quad   0x1fcca94516bd3289
+        .quad   0x448d65aa41420428
+        .quad   0x59c3b7b216a55d62
+        .quad   0x49992cc64e612cd8
+        .quad   0x65bd1bea70f801de
+        .quad   0x1befb7c0fe49e28a
+        .quad   0xa86306cdb1b2ae4a
+        .quad   0x3b7ac0cd265c2a09
+
+        // 2^20 * 8 * B
+
+        .quad   0x822bee438c01bcec
+        .quad   0x530cb525c0fbc73b
+        .quad   0x48519034c1953fe9
+        .quad   0x265cc261e09a0f5b
+        .quad   0xf0d54e4f22ed39a7
+        .quad   0xa2aae91e5608150a
+        .quad   0xf421b2e9eddae875
+        .quad   0x31bc531d6b7de992
+        .quad   0xdf3d134da980f971
+        .quad   0x7a4fb8d1221a22a7
+        .quad   0x3df7d42035aad6d8
+        .quad   0x2a14edcc6a1a125e
+
+        // 2^24 * 1 * B
+
+        .quad   0xdf48ee0752cfce4e
+        .quad   0xc3fffaf306ec08b7
+        .quad   0x05710b2ab95459c4
+        .quad   0x161d25fa963ea38d
+        .quad   0x231a8c570478433c
+        .quad   0xb7b5270ec281439d
+        .quad   0xdbaa99eae3d9079f
+        .quad   0x2c03f5256c2b03d9
+        .quad   0x790f18757b53a47d
+        .quad   0x307b0130cf0c5879
+        .quad   0x31903d77257ef7f9
+        .quad   0x699468bdbd96bbaf
+
+        // 2^24 * 2 * B
+
+        .quad   0xbd1f2f46f4dafecf
+        .quad   0x7cef0114a47fd6f7
+        .quad   0xd31ffdda4a47b37f
+        .quad   0x525219a473905785
+        .quad   0xd8dd3de66aa91948
+        .quad   0x485064c22fc0d2cc
+        .quad   0x9b48246634fdea2f
+        .quad   0x293e1c4e6c4a2e3a
+        .quad   0x376e134b925112e1
+        .quad   0x703778b5dca15da0
+        .quad   0xb04589af461c3111
+        .quad   0x5b605c447f032823
+
+        // 2^24 * 3 * B
+
+        .quad   0xb965805920c47c89
+        .quad   0xe7f0100c923b8fcc
+        .quad   0x0001256502e2ef77
+        .quad   0x24a76dcea8aeb3ee
+        .quad   0x3be9fec6f0e7f04c
+        .quad   0x866a579e75e34962
+        .quad   0x5542ef161e1de61a
+        .quad   0x2f12fef4cc5abdd5
+        .quad   0x0a4522b2dfc0c740
+        .quad   0x10d06e7f40c9a407
+        .quad   0xc6cf144178cff668
+        .quad   0x5e607b2518a43790
+
+        // 2^24 * 4 * B
+
+        .quad   0x58b31d8f6cdf1818
+        .quad   0x35cfa74fc36258a2
+        .quad   0xe1b3ff4f66e61d6e
+        .quad   0x5067acab6ccdd5f7
+        .quad   0xa02c431ca596cf14
+        .quad   0xe3c42d40aed3e400
+        .quad   0xd24526802e0f26db
+        .quad   0x201f33139e457068
+        .quad   0xfd527f6b08039d51
+        .quad   0x18b14964017c0006
+        .quad   0xd5220eb02e25a4a8
+        .quad   0x397cba8862460375
+
+        // 2^24 * 5 * B
+
+        .quad   0x30c13093f05959b2
+        .quad   0xe23aa18de9a97976
+        .quad   0x222fd491721d5e26
+        .quad   0x2339d320766e6c3a
+        .quad   0x7815c3fbc81379e7
+        .quad   0xa6619420dde12af1
+        .quad   0xffa9c0f885a8fdd5
+        .quad   0x771b4022c1e1c252
+        .quad   0xd87dd986513a2fa7
+        .quad   0xf5ac9b71f9d4cf08
+        .quad   0xd06bc31b1ea283b3
+        .quad   0x331a189219971a76
+
+        // 2^24 * 6 * B
+
+        .quad   0xf5166f45fb4f80c6
+        .quad   0x9c36c7de61c775cf
+        .quad   0xe3d4e81b9041d91c
+        .quad   0x31167c6b83bdfe21
+        .quad   0x26512f3a9d7572af
+        .quad   0x5bcbe28868074a9e
+        .quad   0x84edc1c11180f7c4
+        .quad   0x1ac9619ff649a67b
+        .quad   0xf22b3842524b1068
+        .quad   0x5068343bee9ce987
+        .quad   0xfc9d71844a6250c8
+        .quad   0x612436341f08b111
+
+        // 2^24 * 7 * B
+
+        .quad   0xd99d41db874e898d
+        .quad   0x09fea5f16c07dc20
+        .quad   0x793d2c67d00f9bbc
+        .quad   0x46ebe2309e5eff40
+        .quad   0x8b6349e31a2d2638
+        .quad   0x9ddfb7009bd3fd35
+        .quad   0x7f8bf1b8a3a06ba4
+        .quad   0x1522aa3178d90445
+        .quad   0x2c382f5369614938
+        .quad   0xdafe409ab72d6d10
+        .quad   0xe8c83391b646f227
+        .quad   0x45fe70f50524306c
+
+        // 2^24 * 8 * B
+
+        .quad   0xda4875a6960c0b8c
+        .quad   0x5b68d076ef0e2f20
+        .quad   0x07fb51cf3d0b8fd4
+        .quad   0x428d1623a0e392d4
+        .quad   0x62f24920c8951491
+        .quad   0x05f007c83f630ca2
+        .quad   0x6fbb45d2f5c9d4b8
+        .quad   0x16619f6db57a2245
+        .quad   0x084f4a4401a308fd
+        .quad   0xa82219c376a5caac
+        .quad   0xdeb8de4643d1bc7d
+        .quad   0x1d81592d60bd38c6
+
+        // 2^28 * 1 * B
+
+        .quad   0xd833d7beec2a4c38
+        .quad   0x2c9162830acc20ed
+        .quad   0xe93a47aa92df7581
+        .quad   0x702d67a3333c4a81
+        .quad   0x3a4a369a2f89c8a1
+        .quad   0x63137a1d7c8de80d
+        .quad   0xbcac008a78eda015
+        .quad   0x2cb8b3a5b483b03f
+        .quad   0x36e417cbcb1b90a1
+        .quad   0x33b3ddaa7f11794e
+        .quad   0x3f510808885bc607
+        .quad   0x24141dc0e6a8020d
+
+        // 2^28 * 2 * B
+
+        .quad   0x59f73c773fefee9d
+        .quad   0xb3f1ef89c1cf989d
+        .quad   0xe35dfb42e02e545f
+        .quad   0x5766120b47a1b47c
+        .quad   0x91925dccbd83157d
+        .quad   0x3ca1205322cc8094
+        .quad   0x28e57f183f90d6e4
+        .quad   0x1a4714cede2e767b
+        .quad   0xdb20ba0fb8b6b7ff
+        .quad   0xb732c3b677511fa1
+        .quad   0xa92b51c099f02d89
+        .quad   0x4f3875ad489ca5f1
+
+        // 2^28 * 3 * B
+
+        .quad   0xc7fc762f4932ab22
+        .quad   0x7ac0edf72f4c3c1b
+        .quad   0x5f6b55aa9aa895e8
+        .quad   0x3680274dad0a0081
+        .quad   0x79ed13f6ee73eec0
+        .quad   0xa5c6526d69110bb1
+        .quad   0xe48928c38603860c
+        .quad   0x722a1446fd7059f5
+        .quad   0xd0959fe9a8cf8819
+        .quad   0xd0a995508475a99c
+        .quad   0x6eac173320b09cc5
+        .quad   0x628ecf04331b1095
+
+        // 2^28 * 4 * B
+
+        .quad   0x98bcb118a9d0ddbc
+        .quad   0xee449e3408b4802b
+        .quad   0x87089226b8a6b104
+        .quad   0x685f349a45c7915d
+        .quad   0x9b41acf85c74ccf1
+        .quad   0xb673318108265251
+        .quad   0x99c92aed11adb147
+        .quad   0x7a47d70d34ecb40f
+        .quad   0x60a0c4cbcc43a4f5
+        .quad   0x775c66ca3677bea9
+        .quad   0xa17aa1752ff8f5ed
+        .quad   0x11ded9020e01fdc0
+
+        // 2^28 * 5 * B
+
+        .quad   0x890e7809caefe704
+        .quad   0x8728296de30e8c6c
+        .quad   0x4c5cd2a392aeb1c9
+        .quad   0x194263d15771531f
+        .quad   0x471f95b03bea93b7
+        .quad   0x0552d7d43313abd3
+        .quad   0xbd9370e2e17e3f7b
+        .quad   0x7b120f1db20e5bec
+        .quad   0x17d2fb3d86502d7a
+        .quad   0xb564d84450a69352
+        .quad   0x7da962c8a60ed75d
+        .quad   0x00d0f85b318736aa
+
+        // 2^28 * 6 * B
+
+        .quad   0x978b142e777c84fd
+        .quad   0xf402644705a8c062
+        .quad   0xa67ad51be7e612c7
+        .quad   0x2f7b459698dd6a33
+        .quad   0xa6753c1efd7621c1
+        .quad   0x69c0b4a7445671f5
+        .quad   0x971f527405b23c11
+        .quad   0x387bc74851a8c7cd
+        .quad   0x81894b4d4a52a9a8
+        .quad   0xadd93e12f6b8832f
+        .quad   0x184d8548b61bd638
+        .quad   0x3f1c62dbd6c9f6cd
+
+        // 2^28 * 7 * B
+
+        .quad   0x2e8f1f0091910c1f
+        .quad   0xa4df4fe0bff2e12c
+        .quad   0x60c6560aee927438
+        .quad   0x6338283facefc8fa
+        .quad   0x3fad3e40148f693d
+        .quad   0x052656e194eb9a72
+        .quad   0x2f4dcbfd184f4e2f
+        .quad   0x406f8db1c482e18b
+        .quad   0x9e630d2c7f191ee4
+        .quad   0x4fbf8301bc3ff670
+        .quad   0x787d8e4e7afb73c4
+        .quad   0x50d83d5be8f58fa5
+
+        // 2^28 * 8 * B
+
+        .quad   0x85683916c11a1897
+        .quad   0x2d69a4efe506d008
+        .quad   0x39af1378f664bd01
+        .quad   0x65942131361517c6
+        .quad   0xc0accf90b4d3b66d
+        .quad   0xa7059de561732e60
+        .quad   0x033d1f7870c6b0ba
+        .quad   0x584161cd26d946e4
+        .quad   0xbbf2b1a072d27ca2
+        .quad   0xbf393c59fbdec704
+        .quad   0xe98dbbcee262b81e
+        .quad   0x02eebd0b3029b589
+
+        // 2^32 * 1 * B
+
+        .quad   0x61368756a60dac5f
+        .quad   0x17e02f6aebabdc57
+        .quad   0x7f193f2d4cce0f7d
+        .quad   0x20234a7789ecdcf0
+        .quad   0x8765b69f7b85c5e8
+        .quad   0x6ff0678bd168bab2
+        .quad   0x3a70e77c1d330f9b
+        .quad   0x3a5f6d51b0af8e7c
+        .quad   0x76d20db67178b252
+        .quad   0x071c34f9d51ed160
+        .quad   0xf62a4a20b3e41170
+        .quad   0x7cd682353cffe366
+
+        // 2^32 * 2 * B
+
+        .quad   0x0be1a45bd887fab6
+        .quad   0x2a846a32ba403b6e
+        .quad   0xd9921012e96e6000
+        .quad   0x2838c8863bdc0943
+        .quad   0xa665cd6068acf4f3
+        .quad   0x42d92d183cd7e3d3
+        .quad   0x5759389d336025d9
+        .quad   0x3ef0253b2b2cd8ff
+        .quad   0xd16bb0cf4a465030
+        .quad   0xfa496b4115c577ab
+        .quad   0x82cfae8af4ab419d
+        .quad   0x21dcb8a606a82812
+
+        // 2^32 * 3 * B
+
+        .quad   0x5c6004468c9d9fc8
+        .quad   0x2540096ed42aa3cb
+        .quad   0x125b4d4c12ee2f9c
+        .quad   0x0bc3d08194a31dab
+        .quad   0x9a8d00fabe7731ba
+        .quad   0x8203607e629e1889
+        .quad   0xb2cc023743f3d97f
+        .quad   0x5d840dbf6c6f678b
+        .quad   0x706e380d309fe18b
+        .quad   0x6eb02da6b9e165c7
+        .quad   0x57bbba997dae20ab
+        .quad   0x3a4276232ac196dd
+
+        // 2^32 * 4 * B
+
+        .quad   0x4b42432c8a7084fa
+        .quad   0x898a19e3dfb9e545
+        .quad   0xbe9f00219c58e45d
+        .quad   0x1ff177cea16debd1
+        .quad   0x3bf8c172db447ecb
+        .quad   0x5fcfc41fc6282dbd
+        .quad   0x80acffc075aa15fe
+        .quad   0x0770c9e824e1a9f9
+        .quad   0xcf61d99a45b5b5fd
+        .quad   0x860984e91b3a7924
+        .quad   0xe7300919303e3e89
+        .quad   0x39f264fd41500b1e
+
+        // 2^32 * 5 * B
+
+        .quad   0xa7ad3417dbe7e29c
+        .quad   0xbd94376a2b9c139c
+        .quad   0xa0e91b8e93597ba9
+        .quad   0x1712d73468889840
+        .quad   0xd19b4aabfe097be1
+        .quad   0xa46dfce1dfe01929
+        .quad   0xc3c908942ca6f1ff
+        .quad   0x65c621272c35f14e
+        .quad   0xe72b89f8ce3193dd
+        .quad   0x4d103356a125c0bb
+        .quad   0x0419a93d2e1cfe83
+        .quad   0x22f9800ab19ce272
+
+        // 2^32 * 6 * B
+
+        .quad   0x605a368a3e9ef8cb
+        .quad   0xe3e9c022a5504715
+        .quad   0x553d48b05f24248f
+        .quad   0x13f416cd647626e5
+        .quad   0x42029fdd9a6efdac
+        .quad   0xb912cebe34a54941
+        .quad   0x640f64b987bdf37b
+        .quad   0x4171a4d38598cab4
+        .quad   0xfa2758aa99c94c8c
+        .quad   0x23006f6fb000b807
+        .quad   0xfbd291ddadda5392
+        .quad   0x508214fa574bd1ab
+
+        // 2^32 * 7 * B
+
+        .quad   0xc20269153ed6fe4b
+        .quad   0xa65a6739511d77c4
+        .quad   0xcbde26462c14af94
+        .quad   0x22f960ec6faba74b
+        .quad   0x461a15bb53d003d6
+        .quad   0xb2102888bcf3c965
+        .quad   0x27c576756c683a5a
+        .quad   0x3a7758a4c86cb447
+        .quad   0x548111f693ae5076
+        .quad   0x1dae21df1dfd54a6
+        .quad   0x12248c90f3115e65
+        .quad   0x5d9fd15f8de7f494
+
+        // 2^32 * 8 * B
+
+        .quad   0x031408d36d63727f
+        .quad   0x6a379aefd7c7b533
+        .quad   0xa9e18fc5ccaee24b
+        .quad   0x332f35914f8fbed3
+        .quad   0x3f244d2aeed7521e
+        .quad   0x8e3a9028432e9615
+        .quad   0xe164ba772e9c16d4
+        .quad   0x3bc187fa47eb98d8
+        .quad   0x6d470115ea86c20c
+        .quad   0x998ab7cb6c46d125
+        .quad   0xd77832b53a660188
+        .quad   0x450d81ce906fba03
+
+        // 2^36 * 1 * B
+
+        .quad   0xf8ae4d2ad8453902
+        .quad   0x7018058ee8db2d1d
+        .quad   0xaab3995fc7d2c11e
+        .quad   0x53b16d2324ccca79
+        .quad   0x23264d66b2cae0b5
+        .quad   0x7dbaed33ebca6576
+        .quad   0x030ebed6f0d24ac8
+        .quad   0x2a887f78f7635510
+        .quad   0x2a23b9e75c012d4f
+        .quad   0x0c974651cae1f2ea
+        .quad   0x2fb63273675d70ca
+        .quad   0x0ba7250b864403f5
+
+        // 2^36 * 2 * B
+
+        .quad   0xbb0d18fd029c6421
+        .quad   0xbc2d142189298f02
+        .quad   0x8347f8e68b250e96
+        .quad   0x7b9f2fe8032d71c9
+        .quad   0xdd63589386f86d9c
+        .quad   0x61699176e13a85a4
+        .quad   0x2e5111954eaa7d57
+        .quad   0x32c21b57fb60bdfb
+        .quad   0xd87823cd319e0780
+        .quad   0xefc4cfc1897775c5
+        .quad   0x4854fb129a0ab3f7
+        .quad   0x12c49d417238c371
+
+        // 2^36 * 3 * B
+
+        .quad   0x0950b533ffe83769
+        .quad   0x21861c1d8e1d6bd1
+        .quad   0xf022d8381302e510
+        .quad   0x2509200c6391cab4
+        .quad   0x09b3a01783799542
+        .quad   0x626dd08faad5ee3f
+        .quad   0xba00bceeeb70149f
+        .quad   0x1421b246a0a444c9
+        .quad   0x4aa43a8e8c24a7c7
+        .quad   0x04c1f540d8f05ef5
+        .quad   0xadba5e0c0b3eb9dc
+        .quad   0x2ab5504448a49ce3
+
+        // 2^36 * 4 * B
+
+        .quad   0x2ed227266f0f5dec
+        .quad   0x9824ee415ed50824
+        .quad   0x807bec7c9468d415
+        .quad   0x7093bae1b521e23f
+        .quad   0xdc07ac631c5d3afa
+        .quad   0x58615171f9df8c6c
+        .quad   0x72a079d89d73e2b0
+        .quad   0x7301f4ceb4eae15d
+        .quad   0x6409e759d6722c41
+        .quad   0xa674e1cf72bf729b
+        .quad   0xbc0a24eb3c21e569
+        .quad   0x390167d24ebacb23
+
+        // 2^36 * 5 * B
+
+        .quad   0x27f58e3bba353f1c
+        .quad   0x4c47764dbf6a4361
+        .quad   0xafbbc4e56e562650
+        .quad   0x07db2ee6aae1a45d
+        .quad   0xd7bb054ba2f2120b
+        .quad   0xe2b9ceaeb10589b7
+        .quad   0x3fe8bac8f3c0edbe
+        .quad   0x4cbd40767112cb69
+        .quad   0x0b603cc029c58176
+        .quad   0x5988e3825cb15d61
+        .quad   0x2bb61413dcf0ad8d
+        .quad   0x7b8eec6c74183287
+
+        // 2^36 * 6 * B
+
+        .quad   0xe4ca40782cd27cb0
+        .quad   0xdaf9c323fbe967bd
+        .quad   0xb29bd34a8ad41e9e
+        .quad   0x72810497626ede4d
+        .quad   0x32fee570fc386b73
+        .quad   0xda8b0141da3a8cc7
+        .quad   0x975ffd0ac8968359
+        .quad   0x6ee809a1b132a855
+        .quad   0x9444bb31fcfd863a
+        .quad   0x2fe3690a3e4e48c5
+        .quad   0xdc29c867d088fa25
+        .quad   0x13bd1e38d173292e
+
+        // 2^36 * 7 * B
+
+        .quad   0xd32b4cd8696149b5
+        .quad   0xe55937d781d8aab7
+        .quad   0x0bcb2127ae122b94
+        .quad   0x41e86fcfb14099b0
+        .quad   0x223fb5cf1dfac521
+        .quad   0x325c25316f554450
+        .quad   0x030b98d7659177ac
+        .quad   0x1ed018b64f88a4bd
+        .quad   0x3630dfa1b802a6b0
+        .quad   0x880f874742ad3bd5
+        .quad   0x0af90d6ceec5a4d4
+        .quad   0x746a247a37cdc5d9
+
+        // 2^36 * 8 * B
+
+        .quad   0xd531b8bd2b7b9af6
+        .quad   0x5005093537fc5b51
+        .quad   0x232fcf25c593546d
+        .quad   0x20a365142bb40f49
+        .quad   0x6eccd85278d941ed
+        .quad   0x2254ae83d22f7843
+        .quad   0xc522d02e7bbfcdb7
+        .quad   0x681e3351bff0e4e2
+        .quad   0x8b64b59d83034f45
+        .quad   0x2f8b71f21fa20efb
+        .quad   0x69249495ba6550e4
+        .quad   0x539ef98e45d5472b
+
+        // 2^40 * 1 * B
+
+        .quad   0x6e7bb6a1a6205275
+        .quad   0xaa4f21d7413c8e83
+        .quad   0x6f56d155e88f5cb2
+        .quad   0x2de25d4ba6345be1
+        .quad   0xd074d8961cae743f
+        .quad   0xf86d18f5ee1c63ed
+        .quad   0x97bdc55be7f4ed29
+        .quad   0x4cbad279663ab108
+        .quad   0x80d19024a0d71fcd
+        .quad   0xc525c20afb288af8
+        .quad   0xb1a3974b5f3a6419
+        .quad   0x7d7fbcefe2007233
+
+        // 2^40 * 2 * B
+
+        .quad   0xfaef1e6a266b2801
+        .quad   0x866c68c4d5739f16
+        .quad   0xf68a2fbc1b03762c
+        .quad   0x5975435e87b75a8d
+        .quad   0xcd7c5dc5f3c29094
+        .quad   0xc781a29a2a9105ab
+        .quad   0x80c61d36421c3058
+        .quad   0x4f9cd196dcd8d4d7
+        .quad   0x199297d86a7b3768
+        .quad   0xd0d058241ad17a63
+        .quad   0xba029cad5c1c0c17
+        .quad   0x7ccdd084387a0307
+
+        // 2^40 * 3 * B
+
+        .quad   0xdca6422c6d260417
+        .quad   0xae153d50948240bd
+        .quad   0xa9c0c1b4fb68c677
+        .quad   0x428bd0ed61d0cf53
+        .quad   0x9b0c84186760cc93
+        .quad   0xcdae007a1ab32a99
+        .quad   0xa88dec86620bda18
+        .quad   0x3593ca848190ca44
+        .quad   0x9213189a5e849aa7
+        .quad   0xd4d8c33565d8facd
+        .quad   0x8c52545b53fdbbd1
+        .quad   0x27398308da2d63e6
+
+        // 2^40 * 4 * B
+
+        .quad   0x42c38d28435ed413
+        .quad   0xbd50f3603278ccc9
+        .quad   0xbb07ab1a79da03ef
+        .quad   0x269597aebe8c3355
+        .quad   0xb9a10e4c0a702453
+        .quad   0x0fa25866d57d1bde
+        .quad   0xffb9d9b5cd27daf7
+        .quad   0x572c2945492c33fd
+        .quad   0xc77fc745d6cd30be
+        .quad   0xe4dfe8d3e3baaefb
+        .quad   0xa22c8830aa5dda0c
+        .quad   0x7f985498c05bca80
+
+        // 2^40 * 5 * B
+
+        .quad   0x3849ce889f0be117
+        .quad   0x8005ad1b7b54a288
+        .quad   0x3da3c39f23fc921c
+        .quad   0x76c2ec470a31f304
+        .quad   0xd35615520fbf6363
+        .quad   0x08045a45cf4dfba6
+        .quad   0xeec24fbc873fa0c2
+        .quad   0x30f2653cd69b12e7
+        .quad   0x8a08c938aac10c85
+        .quad   0x46179b60db276bcb
+        .quad   0xa920c01e0e6fac70
+        .quad   0x2f1273f1596473da
+
+        // 2^40 * 6 * B
+
+        .quad   0x4739fc7c8ae01e11
+        .quad   0xfd5274904a6aab9f
+        .quad   0x41d98a8287728f2e
+        .quad   0x5d9e572ad85b69f2
+        .quad   0x30488bd755a70bc0
+        .quad   0x06d6b5a4f1d442e7
+        .quad   0xead1a69ebc596162
+        .quad   0x38ac1997edc5f784
+        .quad   0x0666b517a751b13b
+        .quad   0x747d06867e9b858c
+        .quad   0xacacc011454dde49
+        .quad   0x22dfcd9cbfe9e69c
+
+        // 2^40 * 7 * B
+
+        .quad   0x8ddbd2e0c30d0cd9
+        .quad   0xad8e665facbb4333
+        .quad   0x8f6b258c322a961f
+        .quad   0x6b2916c05448c1c7
+        .quad   0x56ec59b4103be0a1
+        .quad   0x2ee3baecd259f969
+        .quad   0x797cb29413f5cd32
+        .quad   0x0fe9877824cde472
+        .quad   0x7edb34d10aba913b
+        .quad   0x4ea3cd822e6dac0e
+        .quad   0x66083dff6578f815
+        .quad   0x4c303f307ff00a17
+
+        // 2^40 * 8 * B
+
+        .quad   0xd30a3bd617b28c85
+        .quad   0xc5d377b739773bea
+        .quad   0xc6c6e78c1e6a5cbf
+        .quad   0x0d61b8f78b2ab7c4
+        .quad   0x29fc03580dd94500
+        .quad   0xecd27aa46fbbec93
+        .quad   0x130a155fc2e2a7f8
+        .quad   0x416b151ab706a1d5
+        .quad   0x56a8d7efe9c136b0
+        .quad   0xbd07e5cd58e44b20
+        .quad   0xafe62fda1b57e0ab
+        .quad   0x191a2af74277e8d2
+
+        // 2^44 * 1 * B
+
+        .quad   0xd550095bab6f4985
+        .quad   0x04f4cd5b4fbfaf1a
+        .quad   0x9d8e2ed12a0c7540
+        .quad   0x2bc24e04b2212286
+        .quad   0x09d4b60b2fe09a14
+        .quad   0xc384f0afdbb1747e
+        .quad   0x58e2ea8978b5fd6e
+        .quad   0x519ef577b5e09b0a
+        .quad   0x1863d7d91124cca9
+        .quad   0x7ac08145b88a708e
+        .quad   0x2bcd7309857031f5
+        .quad   0x62337a6e8ab8fae5
+
+        // 2^44 * 2 * B
+
+        .quad   0x4bcef17f06ffca16
+        .quad   0xde06e1db692ae16a
+        .quad   0x0753702d614f42b0
+        .quad   0x5f6041b45b9212d0
+        .quad   0xd1ab324e1b3a1273
+        .quad   0x18947cf181055340
+        .quad   0x3b5d9567a98c196e
+        .quad   0x7fa00425802e1e68
+        .quad   0x7d531574028c2705
+        .quad   0x80317d69db0d75fe
+        .quad   0x30fface8ef8c8ddd
+        .quad   0x7e9de97bb6c3e998
+
+        // 2^44 * 3 * B
+
+        .quad   0x1558967b9e6585a3
+        .quad   0x97c99ce098e98b92
+        .quad   0x10af149b6eb3adad
+        .quad   0x42181fe8f4d38cfa
+        .quad   0xf004be62a24d40dd
+        .quad   0xba0659910452d41f
+        .quad   0x81c45ee162a44234
+        .quad   0x4cb829d8a22266ef
+        .quad   0x1dbcaa8407b86681
+        .quad   0x081f001e8b26753b
+        .quad   0x3cd7ce6a84048e81
+        .quad   0x78af11633f25f22c
+
+        // 2^44 * 4 * B
+
+        .quad   0x8416ebd40b50babc
+        .quad   0x1508722628208bee
+        .quad   0xa3148fafb9c1c36d
+        .quad   0x0d07daacd32d7d5d
+        .quad   0x3241c00e7d65318c
+        .quad   0xe6bee5dcd0e86de7
+        .quad   0x118b2dc2fbc08c26
+        .quad   0x680d04a7fc603dc3
+        .quad   0xf9c2414a695aa3eb
+        .quad   0xdaa42c4c05a68f21
+        .quad   0x7c6c23987f93963e
+        .quad   0x210e8cd30c3954e3
+
+        // 2^44 * 5 * B
+
+        .quad   0xac4201f210a71c06
+        .quad   0x6a65e0aef3bfb021
+        .quad   0xbc42c35c393632f7
+        .quad   0x56ea8db1865f0742
+        .quad   0x2b50f16137fe6c26
+        .quad   0xe102bcd856e404d8
+        .quad   0x12b0f1414c561f6b
+        .quad   0x51b17bc8d028ec91
+        .quad   0xfff5fb4bcf535119
+        .quad   0xf4989d79df1108a0
+        .quad   0xbdfcea659a3ba325
+        .quad   0x18a11f1174d1a6f2
+
+        // 2^44 * 6 * B
+
+        .quad   0x407375ab3f6bba29
+        .quad   0x9ec3b6d8991e482e
+        .quad   0x99c80e82e55f92e9
+        .quad   0x307c13b6fb0c0ae1
+        .quad   0xfbd63cdad27a5f2c
+        .quad   0xf00fc4bc8aa106d7
+        .quad   0x53fb5c1a8e64a430
+        .quad   0x04eaabe50c1a2e85
+        .quad   0x24751021cb8ab5e7
+        .quad   0xfc2344495c5010eb
+        .quad   0x5f1e717b4e5610a1
+        .quad   0x44da5f18c2710cd5
+
+        // 2^44 * 7 * B
+
+        .quad   0x033cc55ff1b82eb5
+        .quad   0xb15ae36d411cae52
+        .quad   0xba40b6198ffbacd3
+        .quad   0x768edce1532e861f
+        .quad   0x9156fe6b89d8eacc
+        .quad   0xe6b79451e23126a1
+        .quad   0xbd7463d93944eb4e
+        .quad   0x726373f6767203ae
+        .quad   0xe305ca72eb7ef68a
+        .quad   0x662cf31f70eadb23
+        .quad   0x18f026fdb4c45b68
+        .quad   0x513b5384b5d2ecbd
+
+        // 2^44 * 8 * B
+
+        .quad   0x46d46280c729989e
+        .quad   0x4b93fbd05368a5dd
+        .quad   0x63df3f81d1765a89
+        .quad   0x34cebd64b9a0a223
+        .quad   0x5e2702878af34ceb
+        .quad   0x900b0409b946d6ae
+        .quad   0x6512ebf7dabd8512
+        .quad   0x61d9b76988258f81
+        .quad   0xa6c5a71349b7d94b
+        .quad   0xa3f3d15823eb9446
+        .quad   0x0416fbd277484834
+        .quad   0x69d45e6f2c70812f
+
+        // 2^48 * 1 * B
+
+        .quad   0xce16f74bc53c1431
+        .quad   0x2b9725ce2072edde
+        .quad   0xb8b9c36fb5b23ee7
+        .quad   0x7e2e0e450b5cc908
+        .quad   0x9fe62b434f460efb
+        .quad   0xded303d4a63607d6
+        .quad   0xf052210eb7a0da24
+        .quad   0x237e7dbe00545b93
+        .quad   0x013575ed6701b430
+        .quad   0x231094e69f0bfd10
+        .quad   0x75320f1583e47f22
+        .quad   0x71afa699b11155e3
+
+        // 2^48 * 2 * B
+
+        .quad   0x65ce6f9b3953b61d
+        .quad   0xc65839eaafa141e6
+        .quad   0x0f435ffda9f759fe
+        .quad   0x021142e9c2b1c28e
+        .quad   0xea423c1c473b50d6
+        .quad   0x51e87a1f3b38ef10
+        .quad   0x9b84bf5fb2c9be95
+        .quad   0x00731fbc78f89a1c
+        .quad   0xe430c71848f81880
+        .quad   0xbf960c225ecec119
+        .quad   0xb6dae0836bba15e3
+        .quad   0x4c4d6f3347e15808
+
+        // 2^48 * 3 * B
+
+        .quad   0x18f7eccfc17d1fc9
+        .quad   0x6c75f5a651403c14
+        .quad   0xdbde712bf7ee0cdf
+        .quad   0x193fddaaa7e47a22
+        .quad   0x2f0cddfc988f1970
+        .quad   0x6b916227b0b9f51b
+        .quad   0x6ec7b6c4779176be
+        .quad   0x38bf9500a88f9fa8
+        .quad   0x1fd2c93c37e8876f
+        .quad   0xa2f61e5a18d1462c
+        .quad   0x5080f58239241276
+        .quad   0x6a6fb99ebf0d4969
+
+        // 2^48 * 4 * B
+
+        .quad   0x6a46c1bb560855eb
+        .quad   0x2416bb38f893f09d
+        .quad   0xd71d11378f71acc1
+        .quad   0x75f76914a31896ea
+        .quad   0xeeb122b5b6e423c6
+        .quad   0x939d7010f286ff8e
+        .quad   0x90a92a831dcf5d8c
+        .quad   0x136fda9f42c5eb10
+        .quad   0xf94cdfb1a305bdd1
+        .quad   0x0f364b9d9ff82c08
+        .quad   0x2a87d8a5c3bb588a
+        .quad   0x022183510be8dcba
+
+        // 2^48 * 5 * B
+
+        .quad   0x4af766385ead2d14
+        .quad   0xa08ed880ca7c5830
+        .quad   0x0d13a6e610211e3d
+        .quad   0x6a071ce17b806c03
+        .quad   0x9d5a710143307a7f
+        .quad   0xb063de9ec47da45f
+        .quad   0x22bbfe52be927ad3
+        .quad   0x1387c441fd40426c
+        .quad   0xb5d3c3d187978af8
+        .quad   0x722b5a3d7f0e4413
+        .quad   0x0d7b4848bb477ca0
+        .quad   0x3171b26aaf1edc92
+
+        // 2^48 * 6 * B
+
+        .quad   0xa92f319097564ca8
+        .quad   0xff7bb84c2275e119
+        .quad   0x4f55fe37a4875150
+        .quad   0x221fd4873cf0835a
+        .quad   0xa60db7d8b28a47d1
+        .quad   0xa6bf14d61770a4f1
+        .quad   0xd4a1f89353ddbd58
+        .quad   0x6c514a63344243e9
+        .quad   0x2322204f3a156341
+        .quad   0xfb73e0e9ba0a032d
+        .quad   0xfce0dd4c410f030e
+        .quad   0x48daa596fb924aaa
+
+        // 2^48 * 7 * B
+
+        .quad   0x6eca8e665ca59cc7
+        .quad   0xa847254b2e38aca0
+        .quad   0x31afc708d21e17ce
+        .quad   0x676dd6fccad84af7
+        .quad   0x14f61d5dc84c9793
+        .quad   0x9941f9e3ef418206
+        .quad   0xcdf5b88f346277ac
+        .quad   0x58c837fa0e8a79a9
+        .quad   0x0cf9688596fc9058
+        .quad   0x1ddcbbf37b56a01b
+        .quad   0xdcc2e77d4935d66a
+        .quad   0x1c4f73f2c6a57f0a
+
+        // 2^48 * 8 * B
+
+        .quad   0x0e7a4fbd305fa0bb
+        .quad   0x829d4ce054c663ad
+        .quad   0xf421c3832fe33848
+        .quad   0x795ac80d1bf64c42
+        .quad   0xb36e706efc7c3484
+        .quad   0x73dfc9b4c3c1cf61
+        .quad   0xeb1d79c9781cc7e5
+        .quad   0x70459adb7daf675c
+        .quad   0x1b91db4991b42bb3
+        .quad   0x572696234b02dcca
+        .quad   0x9fdf9ee51f8c78dc
+        .quad   0x5fe162848ce21fd3
+
+        // 2^52 * 1 * B
+
+        .quad   0xe2790aae4d077c41
+        .quad   0x8b938270db7469a3
+        .quad   0x6eb632dc8abd16a2
+        .quad   0x720814ecaa064b72
+        .quad   0x315c29c795115389
+        .quad   0xd7e0e507862f74ce
+        .quad   0x0c4a762185927432
+        .quad   0x72de6c984a25a1e4
+        .quad   0xae9ab553bf6aa310
+        .quad   0x050a50a9806d6e1b
+        .quad   0x92bb7403adff5139
+        .quad   0x0394d27645be618b
+
+        // 2^52 * 2 * B
+
+        .quad   0x4d572251857eedf4
+        .quad   0xe3724edde19e93c5
+        .quad   0x8a71420e0b797035
+        .quad   0x3b3c833687abe743
+        .quad   0xf5396425b23545a4
+        .quad   0x15a7a27e98fbb296
+        .quad   0xab6c52bc636fdd86
+        .quad   0x79d995a8419334ee
+        .quad   0xcd8a8ea61195dd75
+        .quad   0xa504d8a81dd9a82f
+        .quad   0x540dca81a35879b6
+        .quad   0x60dd16a379c86a8a
+
+        // 2^52 * 3 * B
+
+        .quad   0x35a2c8487381e559
+        .quad   0x596ffea6d78082cb
+        .quad   0xcb9771ebdba7b653
+        .quad   0x5a08b5019b4da685
+        .quad   0x3501d6f8153e47b8
+        .quad   0xb7a9675414a2f60c
+        .quad   0x112ee8b6455d9523
+        .quad   0x4e62a3c18112ea8a
+        .quad   0xc8d4ac04516ab786
+        .quad   0x595af3215295b23d
+        .quad   0xd6edd234db0230c1
+        .quad   0x0929efe8825b41cc
+
+        // 2^52 * 4 * B
+
+        .quad   0x5f0601d1cbd0f2d3
+        .quad   0x736e412f6132bb7f
+        .quad   0x83604432238dde87
+        .quad   0x1e3a5272f5c0753c
+        .quad   0x8b3172b7ad56651d
+        .quad   0x01581b7a3fabd717
+        .quad   0x2dc94df6424df6e4
+        .quad   0x30376e5d2c29284f
+        .quad   0xd2918da78159a59c
+        .quad   0x6bdc1cd93f0713f3
+        .quad   0x565f7a934acd6590
+        .quad   0x53daacec4cb4c128
+
+        // 2^52 * 5 * B
+
+        .quad   0x4ca73bd79cc8a7d6
+        .quad   0x4d4a738f47e9a9b2
+        .quad   0xf4cbf12942f5fe00
+        .quad   0x01a13ff9bdbf0752
+        .quad   0x99852bc3852cfdb0
+        .quad   0x2cc12e9559d6ed0b
+        .quad   0x70f9e2bf9b5ac27b
+        .quad   0x4f3b8c117959ae99
+        .quad   0x55b6c9c82ff26412
+        .quad   0x1ac4a8c91fb667a8
+        .quad   0xd527bfcfeb778bf2
+        .quad   0x303337da7012a3be
+
+        // 2^52 * 6 * B
+
+        .quad   0x955422228c1c9d7c
+        .quad   0x01fac1371a9b340f
+        .quad   0x7e8d9177925b48d7
+        .quad   0x53f8ad5661b3e31b
+        .quad   0x976d3ccbfad2fdd1
+        .quad   0xcb88839737a640a8
+        .quad   0x2ff00c1d6734cb25
+        .quad   0x269ff4dc789c2d2b
+        .quad   0x0c003fbdc08d678d
+        .quad   0x4d982fa37ead2b17
+        .quad   0xc07e6bcdb2e582f1
+        .quad   0x296c7291df412a44
+
+        // 2^52 * 7 * B
+
+        .quad   0x7903de2b33daf397
+        .quad   0xd0ff0619c9a624b3
+        .quad   0x8a1d252b555b3e18
+        .quad   0x2b6d581c52e0b7c0
+        .quad   0xdfb23205dab8b59e
+        .quad   0x465aeaa0c8092250
+        .quad   0xd133c1189a725d18
+        .quad   0x2327370261f117d1
+        .quad   0x3d0543d3623e7986
+        .quad   0x679414c2c278a354
+        .quad   0xae43f0cc726196f6
+        .quad   0x7836c41f8245eaba
+
+        // 2^52 * 8 * B
+
+        .quad   0xe7a254db49e95a81
+        .quad   0x5192d5d008b0ad73
+        .quad   0x4d20e5b1d00afc07
+        .quad   0x5d55f8012cf25f38
+        .quad   0xca651e848011937c
+        .quad   0xc6b0c46e6ef41a28
+        .quad   0xb7021ba75f3f8d52
+        .quad   0x119dff99ead7b9fd
+        .quad   0x43eadfcbf4b31d4d
+        .quad   0xc6503f7411148892
+        .quad   0xfeee68c5060d3b17
+        .quad   0x329293b3dd4a0ac8
+
+        // 2^56 * 1 * B
+
+        .quad   0x4e59214fe194961a
+        .quad   0x49be7dc70d71cd4f
+        .quad   0x9300cfd23b50f22d
+        .quad   0x4789d446fc917232
+        .quad   0x2879852d5d7cb208
+        .quad   0xb8dedd70687df2e7
+        .quad   0xdc0bffab21687891
+        .quad   0x2b44c043677daa35
+        .quad   0x1a1c87ab074eb78e
+        .quad   0xfac6d18e99daf467
+        .quad   0x3eacbbcd484f9067
+        .quad   0x60c52eef2bb9a4e4
+
+        // 2^56 * 2 * B
+
+        .quad   0x0b5d89bc3bfd8bf1
+        .quad   0xb06b9237c9f3551a
+        .quad   0x0e4c16b0d53028f5
+        .quad   0x10bc9c312ccfcaab
+        .quad   0x702bc5c27cae6d11
+        .quad   0x44c7699b54a48cab
+        .quad   0xefbc4056ba492eb2
+        .quad   0x70d77248d9b6676d
+        .quad   0xaa8ae84b3ec2a05b
+        .quad   0x98699ef4ed1781e0
+        .quad   0x794513e4708e85d1
+        .quad   0x63755bd3a976f413
+
+        // 2^56 * 3 * B
+
+        .quad   0xb55fa03e2ad10853
+        .quad   0x356f75909ee63569
+        .quad   0x9ff9f1fdbe69b890
+        .quad   0x0d8cc1c48bc16f84
+        .quad   0x3dc7101897f1acb7
+        .quad   0x5dda7d5ec165bbd8
+        .quad   0x508e5b9c0fa1020f
+        .quad   0x2763751737c52a56
+        .quad   0x029402d36eb419a9
+        .quad   0xf0b44e7e77b460a5
+        .quad   0xcfa86230d43c4956
+        .quad   0x70c2dd8a7ad166e7
+
+        // 2^56 * 4 * B
+
+        .quad   0x656194509f6fec0e
+        .quad   0xee2e7ea946c6518d
+        .quad   0x9733c1f367e09b5c
+        .quad   0x2e0fac6363948495
+        .quad   0x91d4967db8ed7e13
+        .quad   0x74252f0ad776817a
+        .quad   0xe40982e00d852564
+        .quad   0x32b8613816a53ce5
+        .quad   0x79e7f7bee448cd64
+        .quad   0x6ac83a67087886d0
+        .quad   0xf89fd4d9a0e4db2e
+        .quad   0x4179215c735a4f41
+
+        // 2^56 * 5 * B
+
+        .quad   0x8c7094e7d7dced2a
+        .quad   0x97fb8ac347d39c70
+        .quad   0xe13be033a906d902
+        .quad   0x700344a30cd99d76
+        .quad   0xe4ae33b9286bcd34
+        .quad   0xb7ef7eb6559dd6dc
+        .quad   0x278b141fb3d38e1f
+        .quad   0x31fa85662241c286
+        .quad   0xaf826c422e3622f4
+        .quad   0xc12029879833502d
+        .quad   0x9bc1b7e12b389123
+        .quad   0x24bb2312a9952489
+
+        // 2^56 * 6 * B
+
+        .quad   0xb1a8ed1732de67c3
+        .quad   0x3cb49418461b4948
+        .quad   0x8ebd434376cfbcd2
+        .quad   0x0fee3e871e188008
+        .quad   0x41f80c2af5f85c6b
+        .quad   0x687284c304fa6794
+        .quad   0x8945df99a3ba1bad
+        .quad   0x0d1d2af9ffeb5d16
+        .quad   0xa9da8aa132621edf
+        .quad   0x30b822a159226579
+        .quad   0x4004197ba79ac193
+        .quad   0x16acd79718531d76
+
+        // 2^56 * 7 * B
+
+        .quad   0x72df72af2d9b1d3d
+        .quad   0x63462a36a432245a
+        .quad   0x3ecea07916b39637
+        .quad   0x123e0ef6b9302309
+        .quad   0xc959c6c57887b6ad
+        .quad   0x94e19ead5f90feba
+        .quad   0x16e24e62a342f504
+        .quad   0x164ed34b18161700
+        .quad   0x487ed94c192fe69a
+        .quad   0x61ae2cea3a911513
+        .quad   0x877bf6d3b9a4de27
+        .quad   0x78da0fc61073f3eb
+
+        // 2^56 * 8 * B
+
+        .quad   0x5bf15d28e52bc66a
+        .quad   0x2c47e31870f01a8e
+        .quad   0x2419afbc06c28bdd
+        .quad   0x2d25deeb256b173a
+        .quad   0xa29f80f1680c3a94
+        .quad   0x71f77e151ae9e7e6
+        .quad   0x1100f15848017973
+        .quad   0x054aa4b316b38ddd
+        .quad   0xdfc8468d19267cb8
+        .quad   0x0b28789c66e54daf
+        .quad   0x2aeb1d2a666eec17
+        .quad   0x134610a6ab7da760
+
+        // 2^60 * 1 * B
+
+        .quad   0xcaf55ec27c59b23f
+        .quad   0x99aeed3e154d04f2
+        .quad   0x68441d72e14141f4
+        .quad   0x140345133932a0a2
+        .quad   0xd91430e0dc028c3c
+        .quad   0x0eb955a85217c771
+        .quad   0x4b09e1ed2c99a1fa
+        .quad   0x42881af2bd6a743c
+        .quad   0x7bfec69aab5cad3d
+        .quad   0xc23e8cd34cb2cfad
+        .quad   0x685dd14bfb37d6a2
+        .quad   0x0ad6d64415677a18
+
+        // 2^60 * 2 * B
+
+        .quad   0x781a439e417becb5
+        .quad   0x4ac5938cd10e0266
+        .quad   0x5da385110692ac24
+        .quad   0x11b065a2ade31233
+        .quad   0x7914892847927e9f
+        .quad   0x33dad6ef370aa877
+        .quad   0x1f8f24fa11122703
+        .quad   0x5265ac2f2adf9592
+        .quad   0x405fdd309afcb346
+        .quad   0xd9723d4428e63f54
+        .quad   0x94c01df05f65aaae
+        .quad   0x43e4dc3ae14c0809
+
+        // 2^60 * 3 * B
+
+        .quad   0xbc12c7f1a938a517
+        .quad   0x473028ab3180b2e1
+        .quad   0x3f78571efbcd254a
+        .quad   0x74e534426ff6f90f
+        .quad   0xea6f7ac3adc2c6a3
+        .quad   0xd0e928f6e9717c94
+        .quad   0xe2d379ead645eaf5
+        .quad   0x46dd8785c51ffbbe
+        .quad   0x709801be375c8898
+        .quad   0x4b06dab5e3fd8348
+        .quad   0x75880ced27230714
+        .quad   0x2b09468fdd2f4c42
+
+        // 2^60 * 4 * B
+
+        .quad   0x97c749eeb701cb96
+        .quad   0x83f438d4b6a369c3
+        .quad   0x62962b8b9a402cd9
+        .quad   0x6976c7509888df7b
+        .quad   0x5b97946582ffa02a
+        .quad   0xda096a51fea8f549
+        .quad   0xa06351375f77af9b
+        .quad   0x1bcfde61201d1e76
+        .quad   0x4a4a5490246a59a2
+        .quad   0xd63ebddee87fdd90
+        .quad   0xd9437c670d2371fa
+        .quad   0x69e87308d30f8ed6
+
+        // 2^60 * 5 * B
+
+        .quad   0x435a8bb15656beb0
+        .quad   0xf8fac9ba4f4d5bca
+        .quad   0xb9b278c41548c075
+        .quad   0x3eb0ef76e892b622
+        .quad   0x0f80bf028bc80303
+        .quad   0x6aae16b37a18cefb
+        .quad   0xdd47ea47d72cd6a3
+        .quad   0x61943588f4ed39aa
+        .quad   0xd26e5c3e91039f85
+        .quad   0xc0e9e77df6f33aa9
+        .quad   0xe8968c5570066a93
+        .quad   0x3c34d1881faaaddd
+
+        // 2^60 * 6 * B
+
+        .quad   0x3f9d2b5ea09f9ec0
+        .quad   0x1dab3b6fb623a890
+        .quad   0xa09ba3ea72d926c4
+        .quad   0x374193513fd8b36d
+        .quad   0xbd5b0b8f2fffe0d9
+        .quad   0x6aa254103ed24fb9
+        .quad   0x2ac7d7bcb26821c4
+        .quad   0x605b394b60dca36a
+        .quad   0xb4e856e45a9d1ed2
+        .quad   0xefe848766c97a9a2
+        .quad   0xb104cf641e5eee7d
+        .quad   0x2f50b81c88a71c8f
+
+        // 2^60 * 7 * B
+
+        .quad   0x31723c61fc6811bb
+        .quad   0x9cb450486211800f
+        .quad   0x768933d347995753
+        .quad   0x3491a53502752fcd
+        .quad   0x2b552ca0a7da522a
+        .quad   0x3230b336449b0250
+        .quad   0xf2c4c5bca4b99fb9
+        .quad   0x7b2c674958074a22
+        .quad   0xd55165883ed28cdf
+        .quad   0x12d84fd2d362de39
+        .quad   0x0a874ad3e3378e4f
+        .quad   0x000d2b1f7c763e74
+
+        // 2^60 * 8 * B
+
+        .quad   0x3d420811d06d4a67
+        .quad   0xbefc048590e0ffe3
+        .quad   0xf870c6b7bd487bde
+        .quad   0x6e2a7316319afa28
+        .quad   0x9624778c3e94a8ab
+        .quad   0x0ad6f3cee9a78bec
+        .quad   0x948ac7810d743c4f
+        .quad   0x76627935aaecfccc
+        .quad   0x56a8ac24d6d59a9f
+        .quad   0xc8db753e3096f006
+        .quad   0x477f41e68f4c5299
+        .quad   0x588d851cf6c86114
+
+        // 2^64 * 1 * B
+
+        .quad   0x51138ec78df6b0fe
+        .quad   0x5397da89e575f51b
+        .quad   0x09207a1d717af1b9
+        .quad   0x2102fdba2b20d650
+        .quad   0xcd2a65e777d1f515
+        .quad   0x548991878faa60f1
+        .quad   0xb1b73bbcdabc06e5
+        .quad   0x654878cba97cc9fb
+        .quad   0x969ee405055ce6a1
+        .quad   0x36bca7681251ad29
+        .quad   0x3a1af517aa7da415
+        .quad   0x0ad725db29ecb2ba
+
+        // 2^64 * 2 * B
+
+        .quad   0xdc4267b1834e2457
+        .quad   0xb67544b570ce1bc5
+        .quad   0x1af07a0bf7d15ed7
+        .quad   0x4aefcffb71a03650
+        .quad   0xfec7bc0c9b056f85
+        .quad   0x537d5268e7f5ffd7
+        .quad   0x77afc6624312aefa
+        .quad   0x4f675f5302399fd9
+        .quad   0xc32d36360415171e
+        .quad   0xcd2bef118998483b
+        .quad   0x870a6eadd0945110
+        .quad   0x0bccbb72a2a86561
+
+        // 2^64 * 3 * B
+
+        .quad   0x185e962feab1a9c8
+        .quad   0x86e7e63565147dcd
+        .quad   0xb092e031bb5b6df2
+        .quad   0x4024f0ab59d6b73e
+        .quad   0x186d5e4c50fe1296
+        .quad   0xe0397b82fee89f7e
+        .quad   0x3bc7f6c5507031b0
+        .quad   0x6678fd69108f37c2
+        .quad   0x1586fa31636863c2
+        .quad   0x07f68c48572d33f2
+        .quad   0x4f73cc9f789eaefc
+        .quad   0x2d42e2108ead4701
+
+        // 2^64 * 4 * B
+
+        .quad   0x97f5131594dfd29b
+        .quad   0x6155985d313f4c6a
+        .quad   0xeba13f0708455010
+        .quad   0x676b2608b8d2d322
+        .quad   0x21717b0d0f537593
+        .quad   0x914e690b131e064c
+        .quad   0x1bb687ae752ae09f
+        .quad   0x420bf3a79b423c6e
+        .quad   0x8138ba651c5b2b47
+        .quad   0x8671b6ec311b1b80
+        .quad   0x7bff0cb1bc3135b0
+        .quad   0x745d2ffa9c0cf1e0
+
+        // 2^64 * 5 * B
+
+        .quad   0xbf525a1e2bc9c8bd
+        .quad   0xea5b260826479d81
+        .quad   0xd511c70edf0155db
+        .quad   0x1ae23ceb960cf5d0
+        .quad   0x6036df5721d34e6a
+        .quad   0xb1db8827997bb3d0
+        .quad   0xd3c209c3c8756afa
+        .quad   0x06e15be54c1dc839
+        .quad   0x5b725d871932994a
+        .quad   0x32351cb5ceb1dab0
+        .quad   0x7dc41549dab7ca05
+        .quad   0x58ded861278ec1f7
+
+        // 2^64 * 6 * B
+
+        .quad   0xd8173793f266c55c
+        .quad   0xc8c976c5cc454e49
+        .quad   0x5ce382f8bc26c3a8
+        .quad   0x2ff39de85485f6f9
+        .quad   0x2dfb5ba8b6c2c9a8
+        .quad   0x48eeef8ef52c598c
+        .quad   0x33809107f12d1573
+        .quad   0x08ba696b531d5bd8
+        .quad   0x77ed3eeec3efc57a
+        .quad   0x04e05517d4ff4811
+        .quad   0xea3d7a3ff1a671cb
+        .quad   0x120633b4947cfe54
+
+        // 2^64 * 7 * B
+
+        .quad   0x0b94987891610042
+        .quad   0x4ee7b13cecebfae8
+        .quad   0x70be739594f0a4c0
+        .quad   0x35d30a99b4d59185
+        .quad   0x82bd31474912100a
+        .quad   0xde237b6d7e6fbe06
+        .quad   0xe11e761911ea79c6
+        .quad   0x07433be3cb393bde
+        .quad   0xff7944c05ce997f4
+        .quad   0x575d3de4b05c51a3
+        .quad   0x583381fd5a76847c
+        .quad   0x2d873ede7af6da9f
+
+        // 2^64 * 8 * B
+
+        .quad   0x157a316443373409
+        .quad   0xfab8b7eef4aa81d9
+        .quad   0xb093fee6f5a64806
+        .quad   0x2e773654707fa7b6
+        .quad   0xaa6202e14e5df981
+        .quad   0xa20d59175015e1f5
+        .quad   0x18a275d3bae21d6c
+        .quad   0x0543618a01600253
+        .quad   0x0deabdf4974c23c1
+        .quad   0xaa6f0a259dce4693
+        .quad   0x04202cb8a29aba2c
+        .quad   0x4b1443362d07960d
+
+        // 2^68 * 1 * B
+
+        .quad   0x47b837f753242cec
+        .quad   0x256dc48cc04212f2
+        .quad   0xe222fbfbe1d928c5
+        .quad   0x48ea295bad8a2c07
+        .quad   0x299b1c3f57c5715e
+        .quad   0x96cb929e6b686d90
+        .quad   0x3004806447235ab3
+        .quad   0x2c435c24a44d9fe1
+        .quad   0x0607c97c80f8833f
+        .quad   0x0e851578ca25ec5b
+        .quad   0x54f7450b161ebb6f
+        .quad   0x7bcb4792a0def80e
+
+        // 2^68 * 2 * B
+
+        .quad   0x8487e3d02bc73659
+        .quad   0x4baf8445059979df
+        .quad   0xd17c975adcad6fbf
+        .quad   0x57369f0bdefc96b6
+        .quad   0x1cecd0a0045224c2
+        .quad   0x757f1b1b69e53952
+        .quad   0x775b7a925289f681
+        .quad   0x1b6cc62016736148
+        .quad   0xf1a9990175638698
+        .quad   0x353dd1beeeaa60d3
+        .quad   0x849471334c9ba488
+        .quad   0x63fa6e6843ade311
+
+        // 2^68 * 3 * B
+
+        .quad   0xd15c20536597c168
+        .quad   0x9f73740098d28789
+        .quad   0x18aee7f13257ba1f
+        .quad   0x3418bfda07346f14
+        .quad   0x2195becdd24b5eb7
+        .quad   0x5e41f18cc0cd44f9
+        .quad   0xdf28074441ca9ede
+        .quad   0x07073b98f35b7d67
+        .quad   0xd03c676c4ce530d4
+        .quad   0x0b64c0473b5df9f4
+        .quad   0x065cef8b19b3a31e
+        .quad   0x3084d661533102c9
+
+        // 2^68 * 4 * B
+
+        .quad   0xe1f6b79ebf8469ad
+        .quad   0x15801004e2663135
+        .quad   0x9a498330af74181b
+        .quad   0x3ba2504f049b673c
+        .quad   0x9a6ce876760321fd
+        .quad   0x7fe2b5109eb63ad8
+        .quad   0x00e7d4ae8ac80592
+        .quad   0x73d86b7abb6f723a
+        .quad   0x0b52b5606dba5ab6
+        .quad   0xa9134f0fbbb1edab
+        .quad   0x30a9520d9b04a635
+        .quad   0x6813b8f37973e5db
+
+        // 2^68 * 5 * B
+
+        .quad   0x9854b054334127c1
+        .quad   0x105d047882fbff25
+        .quad   0xdb49f7f944186f4f
+        .quad   0x1768e838bed0b900
+        .quad   0xf194ca56f3157e29
+        .quad   0x136d35705ef528a5
+        .quad   0xdd4cef778b0599bc
+        .quad   0x7d5472af24f833ed
+        .quad   0xd0ef874daf33da47
+        .quad   0x00d3be5db6e339f9
+        .quad   0x3f2a8a2f9c9ceece
+        .quad   0x5d1aeb792352435a
+
+        // 2^68 * 6 * B
+
+        .quad   0xf59e6bb319cd63ca
+        .quad   0x670c159221d06839
+        .quad   0xb06d565b2150cab6
+        .quad   0x20fb199d104f12a3
+        .quad   0x12c7bfaeb61ba775
+        .quad   0xb84e621fe263bffd
+        .quad   0x0b47a5c35c840dcf
+        .quad   0x7e83be0bccaf8634
+        .quad   0x61943dee6d99c120
+        .quad   0x86101f2e460b9fe0
+        .quad   0x6bb2f1518ee8598d
+        .quad   0x76b76289fcc475cc
+
+        // 2^68 * 7 * B
+
+        .quad   0x791b4cc1756286fa
+        .quad   0xdbced317d74a157c
+        .quad   0x7e732421ea72bde6
+        .quad   0x01fe18491131c8e9
+        .quad   0x4245f1a1522ec0b3
+        .quad   0x558785b22a75656d
+        .quad   0x1d485a2548a1b3c0
+        .quad   0x60959eccd58fe09f
+        .quad   0x3ebfeb7ba8ed7a09
+        .quad   0x49fdc2bbe502789c
+        .quad   0x44ebce5d3c119428
+        .quad   0x35e1eb55be947f4a
+
+        // 2^68 * 8 * B
+
+        .quad   0xdbdae701c5738dd3
+        .quad   0xf9c6f635b26f1bee
+        .quad   0x61e96a8042f15ef4
+        .quad   0x3aa1d11faf60a4d8
+        .quad   0x14fd6dfa726ccc74
+        .quad   0x3b084cfe2f53b965
+        .quad   0xf33ae4f552a2c8b4
+        .quad   0x59aab07a0d40166a
+        .quad   0x77bcec4c925eac25
+        .quad   0x1848718460137738
+        .quad   0x5b374337fea9f451
+        .quad   0x1865e78ec8e6aa46
+
+        // 2^72 * 1 * B
+
+        .quad   0xccc4b7c7b66e1f7a
+        .quad   0x44157e25f50c2f7e
+        .quad   0x3ef06dfc713eaf1c
+        .quad   0x582f446752da63f7
+        .quad   0x967c54e91c529ccb
+        .quad   0x30f6269264c635fb
+        .quad   0x2747aff478121965
+        .quad   0x17038418eaf66f5c
+        .quad   0xc6317bd320324ce4
+        .quad   0xa81042e8a4488bc4
+        .quad   0xb21ef18b4e5a1364
+        .quad   0x0c2a1c4bcda28dc9
+
+        // 2^72 * 2 * B
+
+        .quad   0xd24dc7d06f1f0447
+        .quad   0xb2269e3edb87c059
+        .quad   0xd15b0272fbb2d28f
+        .quad   0x7c558bd1c6f64877
+        .quad   0xedc4814869bd6945
+        .quad   0x0d6d907dbe1c8d22
+        .quad   0xc63bd212d55cc5ab
+        .quad   0x5a6a9b30a314dc83
+        .quad   0xd0ec1524d396463d
+        .quad   0x12bb628ac35a24f0
+        .quad   0xa50c3a791cbc5fa4
+        .quad   0x0404a5ca0afbafc3
+
+        // 2^72 * 3 * B
+
+        .quad   0x8c1f40070aa743d6
+        .quad   0xccbad0cb5b265ee8
+        .quad   0x574b046b668fd2de
+        .quad   0x46395bfdcadd9633
+        .quad   0x62bc9e1b2a416fd1
+        .quad   0xb5c6f728e350598b
+        .quad   0x04343fd83d5d6967
+        .quad   0x39527516e7f8ee98
+        .quad   0x117fdb2d1a5d9a9c
+        .quad   0x9c7745bcd1005c2a
+        .quad   0xefd4bef154d56fea
+        .quad   0x76579a29e822d016
+
+        // 2^72 * 4 * B
+
+        .quad   0x45b68e7e49c02a17
+        .quad   0x23cd51a2bca9a37f
+        .quad   0x3ed65f11ec224c1b
+        .quad   0x43a384dc9e05bdb1
+        .quad   0x333cb51352b434f2
+        .quad   0xd832284993de80e1
+        .quad   0xb5512887750d35ce
+        .quad   0x02c514bb2a2777c1
+        .quad   0x684bd5da8bf1b645
+        .quad   0xfb8bd37ef6b54b53
+        .quad   0x313916d7a9b0d253
+        .quad   0x1160920961548059
+
+        // 2^72 * 5 * B
+
+        .quad   0xb44d166929dacfaa
+        .quad   0xda529f4c8413598f
+        .quad   0xe9ef63ca453d5559
+        .quad   0x351e125bc5698e0b
+        .quad   0x7a385616369b4dcd
+        .quad   0x75c02ca7655c3563
+        .quad   0x7dc21bf9d4f18021
+        .quad   0x2f637d7491e6e042
+        .quad   0xd4b49b461af67bbe
+        .quad   0xd603037ac8ab8961
+        .quad   0x71dee19ff9a699fb
+        .quad   0x7f182d06e7ce2a9a
+
+        // 2^72 * 6 * B
+
+        .quad   0x7a7c8e64ab0168ec
+        .quad   0xcb5a4a5515edc543
+        .quad   0x095519d347cd0eda
+        .quad   0x67d4ac8c343e93b0
+        .quad   0x09454b728e217522
+        .quad   0xaa58e8f4d484b8d8
+        .quad   0xd358254d7f46903c
+        .quad   0x44acc043241c5217
+        .quad   0x1c7d6bbb4f7a5777
+        .quad   0x8b35fed4918313e1
+        .quad   0x4adca1c6c96b4684
+        .quad   0x556d1c8312ad71bd
+
+        // 2^72 * 7 * B
+
+        .quad   0x17ef40e30c8d3982
+        .quad   0x31f7073e15a3fa34
+        .quad   0x4f21f3cb0773646e
+        .quad   0x746c6c6d1d824eff
+        .quad   0x81f06756b11be821
+        .quad   0x0faff82310a3f3dd
+        .quad   0xf8b2d0556a99465d
+        .quad   0x097abe38cc8c7f05
+        .quad   0x0c49c9877ea52da4
+        .quad   0x4c4369559bdc1d43
+        .quad   0x022c3809f7ccebd2
+        .quad   0x577e14a34bee84bd
+
+        // 2^72 * 8 * B
+
+        .quad   0xf0e268ac61a73b0a
+        .quad   0xf2fafa103791a5f5
+        .quad   0xc1e13e826b6d00e9
+        .quad   0x60fa7ee96fd78f42
+        .quad   0x94fecebebd4dd72b
+        .quad   0xf46a4fda060f2211
+        .quad   0x124a5977c0c8d1ff
+        .quad   0x705304b8fb009295
+        .quad   0xb63d1d354d296ec6
+        .quad   0xf3c3053e5fad31d8
+        .quad   0x670b958cb4bd42ec
+        .quad   0x21398e0ca16353fd
+
+        // 2^76 * 1 * B
+
+        .quad   0x216ab2ca8da7d2ef
+        .quad   0x366ad9dd99f42827
+        .quad   0xae64b9004fdd3c75
+        .quad   0x403a395b53909e62
+        .quad   0x86c5fc16861b7e9a
+        .quad   0xf6a330476a27c451
+        .quad   0x01667267a1e93597
+        .quad   0x05ffb9cd6082dfeb
+        .quad   0xa617fa9ff53f6139
+        .quad   0x60f2b5e513e66cb6
+        .quad   0xd7a8beefb3448aa4
+        .quad   0x7a2932856f5ea192
+
+        // 2^76 * 2 * B
+
+        .quad   0x0b39d761b02de888
+        .quad   0x5f550e7ed2414e1f
+        .quad   0xa6bfa45822e1a940
+        .quad   0x050a2f7dfd447b99
+        .quad   0xb89c444879639302
+        .quad   0x4ae4f19350c67f2c
+        .quad   0xf0b35da8c81af9c6
+        .quad   0x39d0003546871017
+        .quad   0x437c3b33a650db77
+        .quad   0x6bafe81dbac52bb2
+        .quad   0xfe99402d2db7d318
+        .quad   0x2b5b7eec372ba6ce
+
+        // 2^76 * 3 * B
+
+        .quad   0xb3bc4bbd83f50eef
+        .quad   0x508f0c998c927866
+        .quad   0x43e76587c8b7e66e
+        .quad   0x0f7655a3a47f98d9
+        .quad   0xa694404d613ac8f4
+        .quad   0x500c3c2bfa97e72c
+        .quad   0x874104d21fcec210
+        .quad   0x1b205fb38604a8ee
+        .quad   0x55ecad37d24b133c
+        .quad   0x441e147d6038c90b
+        .quad   0x656683a1d62c6fee
+        .quad   0x0157d5dc87e0ecae
+
+        // 2^76 * 4 * B
+
+        .quad   0xf2a7af510354c13d
+        .quad   0xd7a0b145aa372b60
+        .quad   0x2869b96a05a3d470
+        .quad   0x6528e42d82460173
+        .quad   0x95265514d71eb524
+        .quad   0xe603d8815df14593
+        .quad   0x147cdf410d4de6b7
+        .quad   0x5293b1730437c850
+        .quad   0x23d0e0814bccf226
+        .quad   0x92c745cd8196fb93
+        .quad   0x8b61796c59541e5b
+        .quad   0x40a44df0c021f978
+
+        // 2^76 * 5 * B
+
+        .quad   0xdaa869894f20ea6a
+        .quad   0xea14a3d14c620618
+        .quad   0x6001fccb090bf8be
+        .quad   0x35f4e822947e9cf0
+        .quad   0x86c96e514bc5d095
+        .quad   0xf20d4098fca6804a
+        .quad   0x27363d89c826ea5d
+        .quad   0x39ca36565719cacf
+        .quad   0x97506f2f6f87b75c
+        .quad   0xc624aea0034ae070
+        .quad   0x1ec856e3aad34dd6
+        .quad   0x055b0be0e440e58f
+
+        // 2^76 * 6 * B
+
+        .quad   0x6469a17d89735d12
+        .quad   0xdb6f27d5e662b9f1
+        .quad   0x9fcba3286a395681
+        .quad   0x363b8004d269af25
+        .quad   0x4d12a04b6ea33da2
+        .quad   0x57cf4c15e36126dd
+        .quad   0x90ec9675ee44d967
+        .quad   0x64ca348d2a985aac
+        .quad   0x99588e19e4c4912d
+        .quad   0xefcc3b4e1ca5ce6b
+        .quad   0x4522ea60fa5b98d5
+        .quad   0x7064bbab1de4a819
+
+        // 2^76 * 7 * B
+
+        .quad   0xb919e1515a770641
+        .quad   0xa9a2e2c74e7f8039
+        .quad   0x7527250b3df23109
+        .quad   0x756a7330ac27b78b
+        .quad   0xa290c06142542129
+        .quad   0xf2e2c2aebe8d5b90
+        .quad   0xcf2458db76abfe1b
+        .quad   0x02157ade83d626bf
+        .quad   0x3e46972a1b9a038b
+        .quad   0x2e4ee66a7ee03fb4
+        .quad   0x81a248776edbb4ca
+        .quad   0x1a944ee88ecd0563
+
+        // 2^76 * 8 * B
+
+        .quad   0xd5a91d1151039372
+        .quad   0x2ed377b799ca26de
+        .quad   0xa17202acfd366b6b
+        .quad   0x0730291bd6901995
+        .quad   0xbb40a859182362d6
+        .quad   0xb99f55778a4d1abb
+        .quad   0x8d18b427758559f6
+        .quad   0x26c20fe74d26235a
+        .quad   0x648d1d9fe9cc22f5
+        .quad   0x66bc561928dd577c
+        .quad   0x47d3ed21652439d1
+        .quad   0x49d271acedaf8b49
+
+        // 2^80 * 1 * B
+
+        .quad   0x89f5058a382b33f3
+        .quad   0x5ae2ba0bad48c0b4
+        .quad   0x8f93b503a53db36e
+        .quad   0x5aa3ed9d95a232e6
+        .quad   0x2798aaf9b4b75601
+        .quad   0x5eac72135c8dad72
+        .quad   0xd2ceaa6161b7a023
+        .quad   0x1bbfb284e98f7d4e
+        .quad   0x656777e9c7d96561
+        .quad   0xcb2b125472c78036
+        .quad   0x65053299d9506eee
+        .quad   0x4a07e14e5e8957cc
+
+        // 2^80 * 2 * B
+
+        .quad   0x4ee412cb980df999
+        .quad   0xa315d76f3c6ec771
+        .quad   0xbba5edde925c77fd
+        .quad   0x3f0bac391d313402
+        .quad   0x240b58cdc477a49b
+        .quad   0xfd38dade6447f017
+        .quad   0x19928d32a7c86aad
+        .quad   0x50af7aed84afa081
+        .quad   0x6e4fde0115f65be5
+        .quad   0x29982621216109b2
+        .quad   0x780205810badd6d9
+        .quad   0x1921a316baebd006
+
+        // 2^80 * 3 * B
+
+        .quad   0x89422f7edfb870fc
+        .quad   0x2c296beb4f76b3bd
+        .quad   0x0738f1d436c24df7
+        .quad   0x6458df41e273aeb0
+        .quad   0xd75aad9ad9f3c18b
+        .quad   0x566a0eef60b1c19c
+        .quad   0x3e9a0bac255c0ed9
+        .quad   0x7b049deca062c7f5
+        .quad   0xdccbe37a35444483
+        .quad   0x758879330fedbe93
+        .quad   0x786004c312c5dd87
+        .quad   0x6093dccbc2950e64
+
+        // 2^80 * 4 * B
+
+        .quad   0x1ff39a8585e0706d
+        .quad   0x36d0a5d8b3e73933
+        .quad   0x43b9f2e1718f453b
+        .quad   0x57d1ea084827a97c
+        .quad   0x6bdeeebe6084034b
+        .quad   0x3199c2b6780fb854
+        .quad   0x973376abb62d0695
+        .quad   0x6e3180c98b647d90
+        .quad   0xee7ab6e7a128b071
+        .quad   0xa4c1596d93a88baa
+        .quad   0xf7b4de82b2216130
+        .quad   0x363e999ddd97bd18
+
+        // 2^80 * 5 * B
+
+        .quad   0x96a843c135ee1fc4
+        .quad   0x976eb35508e4c8cf
+        .quad   0xb42f6801b58cd330
+        .quad   0x48ee9b78693a052b
+        .quad   0x2f1848dce24baec6
+        .quad   0x769b7255babcaf60
+        .quad   0x90cb3c6e3cefe931
+        .quad   0x231f979bc6f9b355
+        .quad   0x5c31de4bcc2af3c6
+        .quad   0xb04bb030fe208d1f
+        .quad   0xb78d7009c14fb466
+        .quad   0x079bfa9b08792413
+
+        // 2^80 * 6 * B
+
+        .quad   0xe3903a51da300df4
+        .quad   0x843964233da95ab0
+        .quad   0xed3cf12d0b356480
+        .quad   0x038c77f684817194
+        .quad   0xf3c9ed80a2d54245
+        .quad   0x0aa08b7877f63952
+        .quad   0xd76dac63d1085475
+        .quad   0x1ef4fb159470636b
+        .quad   0x854e5ee65b167bec
+        .quad   0x59590a4296d0cdc2
+        .quad   0x72b2df3498102199
+        .quad   0x575ee92a4a0bff56
+
+        // 2^80 * 7 * B
+
+        .quad   0xd4c080908a182fcf
+        .quad   0x30e170c299489dbd
+        .quad   0x05babd5752f733de
+        .quad   0x43d4e7112cd3fd00
+        .quad   0x5d46bc450aa4d801
+        .quad   0xc3af1227a533b9d8
+        .quad   0x389e3b262b8906c2
+        .quad   0x200a1e7e382f581b
+        .quad   0x518db967eaf93ac5
+        .quad   0x71bc989b056652c0
+        .quad   0xfe2b85d9567197f5
+        .quad   0x050eca52651e4e38
+
+        // 2^80 * 8 * B
+
+        .quad   0xc3431ade453f0c9c
+        .quad   0xe9f5045eff703b9b
+        .quad   0xfcd97ac9ed847b3d
+        .quad   0x4b0ee6c21c58f4c6
+        .quad   0x97ac397660e668ea
+        .quad   0x9b19bbfe153ab497
+        .quad   0x4cb179b534eca79f
+        .quad   0x6151c09fa131ae57
+        .quad   0x3af55c0dfdf05d96
+        .quad   0xdd262ee02ab4ee7a
+        .quad   0x11b2bb8712171709
+        .quad   0x1fef24fa800f030b
+
+        // 2^84 * 1 * B
+
+        .quad   0xb496123a6b6c6609
+        .quad   0xa750fe8580ab5938
+        .quad   0xf471bf39b7c27a5f
+        .quad   0x507903ce77ac193c
+        .quad   0xff91a66a90166220
+        .quad   0xf22552ae5bf1e009
+        .quad   0x7dff85d87f90df7c
+        .quad   0x4f620ffe0c736fb9
+        .quad   0x62f90d65dfde3e34
+        .quad   0xcf28c592b9fa5fad
+        .quad   0x99c86ef9c6164510
+        .quad   0x25d448044a256c84
+
+        // 2^84 * 2 * B
+
+        .quad   0xbd68230ec7e9b16f
+        .quad   0x0eb1b9c1c1c5795d
+        .quad   0x7943c8c495b6b1ff
+        .quad   0x2f9faf620bbacf5e
+        .quad   0x2c7c4415c9022b55
+        .quad   0x56a0d241812eb1fe
+        .quad   0xf02ea1c9d7b65e0d
+        .quad   0x4180512fd5323b26
+        .quad   0xa4ff3e698a48a5db
+        .quad   0xba6a3806bd95403b
+        .quad   0x9f7ce1af47d5b65d
+        .quad   0x15e087e55939d2fb
+
+        // 2^84 * 3 * B
+
+        .quad   0x12207543745c1496
+        .quad   0xdaff3cfdda38610c
+        .quad   0xe4e797272c71c34f
+        .quad   0x39c07b1934bdede9
+        .quad   0x8894186efb963f38
+        .quad   0x48a00e80dc639bd5
+        .quad   0xa4e8092be96c1c99
+        .quad   0x5a097d54ca573661
+        .quad   0x2d45892b17c9e755
+        .quad   0xd033fd7289308df8
+        .quad   0x6c2fe9d9525b8bd9
+        .quad   0x2edbecf1c11cc079
+
+        // 2^84 * 4 * B
+
+        .quad   0x1616a4e3c715a0d2
+        .quad   0x53623cb0f8341d4d
+        .quad   0x96ef5329c7e899cb
+        .quad   0x3d4e8dbba668baa6
+        .quad   0xee0f0fddd087a25f
+        .quad   0x9c7531555c3e34ee
+        .quad   0x660c572e8fab3ab5
+        .quad   0x0854fc44544cd3b2
+        .quad   0x61eba0c555edad19
+        .quad   0x24b533fef0a83de6
+        .quad   0x3b77042883baa5f8
+        .quad   0x678f82b898a47e8d
+
+        // 2^84 * 5 * B
+
+        .quad   0xb1491d0bd6900c54
+        .quad   0x3539722c9d132636
+        .quad   0x4db928920b362bc9
+        .quad   0x4d7cd1fea68b69df
+        .quad   0x1e09d94057775696
+        .quad   0xeed1265c3cd951db
+        .quad   0xfa9dac2b20bce16f
+        .quad   0x0f7f76e0e8d089f4
+        .quad   0x36d9ebc5d485b00c
+        .quad   0xa2596492e4adb365
+        .quad   0xc1659480c2119ccd
+        .quad   0x45306349186e0d5f
+
+        // 2^84 * 6 * B
+
+        .quad   0x94ddd0c1a6cdff1d
+        .quad   0x55f6f115e84213ae
+        .quad   0x6c935f85992fcf6a
+        .quad   0x067ee0f54a37f16f
+        .quad   0x96a414ec2b072491
+        .quad   0x1bb2218127a7b65b
+        .quad   0x6d2849596e8a4af0
+        .quad   0x65f3b08ccd27765f
+        .quad   0xecb29fff199801f7
+        .quad   0x9d361d1fa2a0f72f
+        .quad   0x25f11d2375fd2f49
+        .quad   0x124cefe80fe10fe2
+
+        // 2^84 * 7 * B
+
+        .quad   0x4c126cf9d18df255
+        .quad   0xc1d471e9147a63b6
+        .quad   0x2c6d3c73f3c93b5f
+        .quad   0x6be3a6a2e3ff86a2
+        .quad   0x1518e85b31b16489
+        .quad   0x8faadcb7db710bfb
+        .quad   0x39b0bdf4a14ae239
+        .quad   0x05f4cbea503d20c1
+        .quad   0xce040e9ec04145bc
+        .quad   0xc71ff4e208f6834c
+        .quad   0xbd546e8dab8847a3
+        .quad   0x64666aa0a4d2aba5
+
+        // 2^84 * 8 * B
+
+        .quad   0x6841435a7c06d912
+        .quad   0xca123c21bb3f830b
+        .quad   0xd4b37b27b1cbe278
+        .quad   0x1d753b84c76f5046
+        .quad   0xb0c53bf73337e94c
+        .quad   0x7cb5697e11e14f15
+        .quad   0x4b84abac1930c750
+        .quad   0x28dd4abfe0640468
+        .quad   0x7dc0b64c44cb9f44
+        .quad   0x18a3e1ace3925dbf
+        .quad   0x7a3034862d0457c4
+        .quad   0x4c498bf78a0c892e
+
+        // 2^88 * 1 * B
+
+        .quad   0x37d653fb1aa73196
+        .quad   0x0f9495303fd76418
+        .quad   0xad200b09fb3a17b2
+        .quad   0x544d49292fc8613e
+        .quad   0x22d2aff530976b86
+        .quad   0x8d90b806c2d24604
+        .quad   0xdca1896c4de5bae5
+        .quad   0x28005fe6c8340c17
+        .quad   0x6aefba9f34528688
+        .quad   0x5c1bff9425107da1
+        .quad   0xf75bbbcd66d94b36
+        .quad   0x72e472930f316dfa
+
+        // 2^88 * 2 * B
+
+        .quad   0x2695208c9781084f
+        .quad   0xb1502a0b23450ee1
+        .quad   0xfd9daea603efde02
+        .quad   0x5a9d2e8c2733a34c
+        .quad   0x07f3f635d32a7627
+        .quad   0x7aaa4d865f6566f0
+        .quad   0x3c85e79728d04450
+        .quad   0x1fee7f000fe06438
+        .quad   0x765305da03dbf7e5
+        .quad   0xa4daf2491434cdbd
+        .quad   0x7b4ad5cdd24a88ec
+        .quad   0x00f94051ee040543
+
+        // 2^88 * 3 * B
+
+        .quad   0x8d356b23c3d330b2
+        .quad   0xf21c8b9bb0471b06
+        .quad   0xb36c316c6e42b83c
+        .quad   0x07d79c7e8beab10d
+        .quad   0xd7ef93bb07af9753
+        .quad   0x583ed0cf3db766a7
+        .quad   0xce6998bf6e0b1ec5
+        .quad   0x47b7ffd25dd40452
+        .quad   0x87fbfb9cbc08dd12
+        .quad   0x8a066b3ae1eec29b
+        .quad   0x0d57242bdb1fc1bf
+        .quad   0x1c3520a35ea64bb6
+
+        // 2^88 * 4 * B
+
+        .quad   0x80d253a6bccba34a
+        .quad   0x3e61c3a13838219b
+        .quad   0x90c3b6019882e396
+        .quad   0x1c3d05775d0ee66f
+        .quad   0xcda86f40216bc059
+        .quad   0x1fbb231d12bcd87e
+        .quad   0xb4956a9e17c70990
+        .quad   0x38750c3b66d12e55
+        .quad   0x692ef1409422e51a
+        .quad   0xcbc0c73c2b5df671
+        .quad   0x21014fe7744ce029
+        .quad   0x0621e2c7d330487c
+
+        // 2^88 * 5 * B
+
+        .quad   0xaf9860cc8259838d
+        .quad   0x90ea48c1c69f9adc
+        .quad   0x6526483765581e30
+        .quad   0x0007d6097bd3a5bc
+        .quad   0xb7ae1796b0dbf0f3
+        .quad   0x54dfafb9e17ce196
+        .quad   0x25923071e9aaa3b4
+        .quad   0x5d8e589ca1002e9d
+        .quad   0xc0bf1d950842a94b
+        .quad   0xb2d3c363588f2e3e
+        .quad   0x0a961438bb51e2ef
+        .quad   0x1583d7783c1cbf86
+
+        // 2^88 * 6 * B
+
+        .quad   0xeceea2ef5da27ae1
+        .quad   0x597c3a1455670174
+        .quad   0xc9a62a126609167a
+        .quad   0x252a5f2e81ed8f70
+        .quad   0x90034704cc9d28c7
+        .quad   0x1d1b679ef72cc58f
+        .quad   0x16e12b5fbe5b8726
+        .quad   0x4958064e83c5580a
+        .quad   0x0d2894265066e80d
+        .quad   0xfcc3f785307c8c6b
+        .quad   0x1b53da780c1112fd
+        .quad   0x079c170bd843b388
+
+        // 2^88 * 7 * B
+
+        .quad   0x0506ece464fa6fff
+        .quad   0xbee3431e6205e523
+        .quad   0x3579422451b8ea42
+        .quad   0x6dec05e34ac9fb00
+        .quad   0xcdd6cd50c0d5d056
+        .quad   0x9af7686dbb03573b
+        .quad   0x3ca6723ff3c3ef48
+        .quad   0x6768c0d7317b8acc
+        .quad   0x94b625e5f155c1b3
+        .quad   0x417bf3a7997b7b91
+        .quad   0xc22cbddc6d6b2600
+        .quad   0x51445e14ddcd52f4
+
+        // 2^88 * 8 * B
+
+        .quad   0x57502b4b3b144951
+        .quad   0x8e67ff6b444bbcb3
+        .quad   0xb8bd6927166385db
+        .quad   0x13186f31e39295c8
+        .quad   0x893147ab2bbea455
+        .quad   0x8c53a24f92079129
+        .quad   0x4b49f948be30f7a7
+        .quad   0x12e990086e4fd43d
+        .quad   0xf10c96b37fdfbb2e
+        .quad   0x9f9a935e121ceaf9
+        .quad   0xdf1136c43a5b983f
+        .quad   0x77b2e3f05d3e99af
+
+        // 2^92 * 1 * B
+
+        .quad   0xfd0d75879cf12657
+        .quad   0xe82fef94e53a0e29
+        .quad   0xcc34a7f05bbb4be7
+        .quad   0x0b251172a50c38a2
+        .quad   0x9532f48fcc5cd29b
+        .quad   0x2ba851bea3ce3671
+        .quad   0x32dacaa051122941
+        .quad   0x478d99d9350004f2
+        .quad   0x1d5ad94890bb02c0
+        .quad   0x50e208b10ec25115
+        .quad   0xa26a22894ef21702
+        .quad   0x4dc923343b524805
+
+        // 2^92 * 2 * B
+
+        .quad   0xe3828c400f8086b6
+        .quad   0x3f77e6f7979f0dc8
+        .quad   0x7ef6de304df42cb4
+        .quad   0x5265797cb6abd784
+        .quad   0x3ad3e3ebf36c4975
+        .quad   0xd75d25a537862125
+        .quad   0xe873943da025a516
+        .quad   0x6bbc7cb4c411c847
+        .quad   0x3c6f9cd1d4a50d56
+        .quad   0xb6244077c6feab7e
+        .quad   0x6ff9bf483580972e
+        .quad   0x00375883b332acfb
+
+        // 2^92 * 3 * B
+
+        .quad   0x0001b2cd28cb0940
+        .quad   0x63fb51a06f1c24c9
+        .quad   0xb5ad8691dcd5ca31
+        .quad   0x67238dbd8c450660
+        .quad   0xc98bec856c75c99c
+        .quad   0xe44184c000e33cf4
+        .quad   0x0a676b9bba907634
+        .quad   0x669e2cb571f379d7
+        .quad   0xcb116b73a49bd308
+        .quad   0x025aad6b2392729e
+        .quad   0xb4793efa3f55d9b1
+        .quad   0x72a1056140678bb9
+
+        // 2^92 * 4 * B
+
+        .quad   0xa2b6812b1cc9249d
+        .quad   0x62866eee21211f58
+        .quad   0x2cb5c5b85df10ece
+        .quad   0x03a6b259e263ae00
+        .quad   0x0d8d2909e2e505b6
+        .quad   0x98ca78abc0291230
+        .quad   0x77ef5569a9b12327
+        .quad   0x7c77897b81439b47
+        .quad   0xf1c1b5e2de331cb5
+        .quad   0x5a9f5d8e15fca420
+        .quad   0x9fa438f17bd932b1
+        .quad   0x2a381bf01c6146e7
+
+        // 2^92 * 5 * B
+
+        .quad   0xac9b9879cfc811c1
+        .quad   0x8b7d29813756e567
+        .quad   0x50da4e607c70edfc
+        .quad   0x5dbca62f884400b6
+        .quad   0xf7c0be32b534166f
+        .quad   0x27e6ca6419cf70d4
+        .quad   0x934df7d7a957a759
+        .quad   0x5701461dabdec2aa
+        .quad   0x2c6747402c915c25
+        .quad   0x1bdcd1a80b0d340a
+        .quad   0x5e5601bd07b43f5f
+        .quad   0x2555b4e05539a242
+
+        // 2^92 * 6 * B
+
+        .quad   0x6fc09f5266ddd216
+        .quad   0xdce560a7c8e37048
+        .quad   0xec65939da2df62fd
+        .quad   0x7a869ae7e52ed192
+        .quad   0x78409b1d87e463d4
+        .quad   0xad4da95acdfb639d
+        .quad   0xec28773755259b9c
+        .quad   0x69c806e9c31230ab
+        .quad   0x7b48f57414bb3f22
+        .quad   0x68c7cee4aedccc88
+        .quad   0xed2f936179ed80be
+        .quad   0x25d70b885f77bc4b
+
+        // 2^92 * 7 * B
+
+        .quad   0x4151c3d9762bf4de
+        .quad   0x083f435f2745d82b
+        .quad   0x29775a2e0d23ddd5
+        .quad   0x138e3a6269a5db24
+        .quad   0x98459d29bb1ae4d4
+        .quad   0x56b9c4c739f954ec
+        .quad   0x832743f6c29b4b3e
+        .quad   0x21ea8e2798b6878a
+        .quad   0x87bef4b46a5a7b9c
+        .quad   0xd2299d1b5fc1d062
+        .quad   0x82409818dd321648
+        .quad   0x5c5abeb1e5a2e03d
+
+        // 2^92 * 8 * B
+
+        .quad   0x14722af4b73c2ddb
+        .quad   0xbc470c5f5a05060d
+        .quad   0x00943eac2581b02e
+        .quad   0x0e434b3b1f499c8f
+        .quad   0x02cde6de1306a233
+        .quad   0x7b5a52a2116f8ec7
+        .quad   0xe1c681f4c1163b5b
+        .quad   0x241d350660d32643
+        .quad   0x6be4404d0ebc52c7
+        .quad   0xae46233bb1a791f5
+        .quad   0x2aec170ed25db42b
+        .quad   0x1d8dfd966645d694
+
+        // 2^96 * 1 * B
+
+        .quad   0x296fa9c59c2ec4de
+        .quad   0xbc8b61bf4f84f3cb
+        .quad   0x1c7706d917a8f908
+        .quad   0x63b795fc7ad3255d
+        .quad   0xd598639c12ddb0a4
+        .quad   0xa5d19f30c024866b
+        .quad   0xd17c2f0358fce460
+        .quad   0x07a195152e095e8a
+        .quad   0xa8368f02389e5fc8
+        .quad   0x90433b02cf8de43b
+        .quad   0xafa1fd5dc5412643
+        .quad   0x3e8fe83d032f0137
+
+        // 2^96 * 2 * B
+
+        .quad   0x2f8b15b90570a294
+        .quad   0x94f2427067084549
+        .quad   0xde1c5ae161bbfd84
+        .quad   0x75ba3b797fac4007
+        .quad   0x08704c8de8efd13c
+        .quad   0xdfc51a8e33e03731
+        .quad   0xa59d5da51260cde3
+        .quad   0x22d60899a6258c86
+        .quad   0x6239dbc070cdd196
+        .quad   0x60fe8a8b6c7d8a9a
+        .quad   0xb38847bceb401260
+        .quad   0x0904d07b87779e5e
+
+        // 2^96 * 3 * B
+
+        .quad   0xb4ce1fd4ddba919c
+        .quad   0xcf31db3ec74c8daa
+        .quad   0x2c63cc63ad86cc51
+        .quad   0x43e2143fbc1dde07
+        .quad   0xf4322d6648f940b9
+        .quad   0x06952f0cbd2d0c39
+        .quad   0x167697ada081f931
+        .quad   0x6240aacebaf72a6c
+        .quad   0xf834749c5ba295a0
+        .quad   0xd6947c5bca37d25a
+        .quad   0x66f13ba7e7c9316a
+        .quad   0x56bdaf238db40cac
+
+        // 2^96 * 4 * B
+
+        .quad   0x362ab9e3f53533eb
+        .quad   0x338568d56eb93d40
+        .quad   0x9e0e14521d5a5572
+        .quad   0x1d24a86d83741318
+        .quad   0x1310d36cc19d3bb2
+        .quad   0x062a6bb7622386b9
+        .quad   0x7c9b8591d7a14f5c
+        .quad   0x03aa31507e1e5754
+        .quad   0xf4ec7648ffd4ce1f
+        .quad   0xe045eaf054ac8c1c
+        .quad   0x88d225821d09357c
+        .quad   0x43b261dc9aeb4859
+
+        // 2^96 * 5 * B
+
+        .quad   0xe55b1e1988bb79bb
+        .quad   0xa09ed07dc17a359d
+        .quad   0xb02c2ee2603dea33
+        .quad   0x326055cf5b276bc2
+        .quad   0x19513d8b6c951364
+        .quad   0x94fe7126000bf47b
+        .quad   0x028d10ddd54f9567
+        .quad   0x02b4d5e242940964
+        .quad   0xb4a155cb28d18df2
+        .quad   0xeacc4646186ce508
+        .quad   0xc49cf4936c824389
+        .quad   0x27a6c809ae5d3410
+
+        // 2^96 * 6 * B
+
+        .quad   0x8ba6ebcd1f0db188
+        .quad   0x37d3d73a675a5be8
+        .quad   0xf22edfa315f5585a
+        .quad   0x2cb67174ff60a17e
+        .quad   0xcd2c270ac43d6954
+        .quad   0xdd4a3e576a66cab2
+        .quad   0x79fa592469d7036c
+        .quad   0x221503603d8c2599
+        .quad   0x59eecdf9390be1d0
+        .quad   0xa9422044728ce3f1
+        .quad   0x82891c667a94f0f4
+        .quad   0x7b1df4b73890f436
+
+        // 2^96 * 7 * B
+
+        .quad   0xe492f2e0b3b2a224
+        .quad   0x7c6c9e062b551160
+        .quad   0x15eb8fe20d7f7b0e
+        .quad   0x61fcef2658fc5992
+        .quad   0x5f2e221807f8f58c
+        .quad   0xe3555c9fd49409d4
+        .quad   0xb2aaa88d1fb6a630
+        .quad   0x68698245d352e03d
+        .quad   0xdbb15d852a18187a
+        .quad   0xf3e4aad386ddacd7
+        .quad   0x44bae2810ff6c482
+        .quad   0x46cf4c473daf01cf
+
+        // 2^96 * 8 * B
+
+        .quad   0x426525ed9ec4e5f9
+        .quad   0x0e5eda0116903303
+        .quad   0x72b1a7f2cbe5cadc
+        .quad   0x29387bcd14eb5f40
+        .quad   0x213c6ea7f1498140
+        .quad   0x7c1e7ef8392b4854
+        .quad   0x2488c38c5629ceba
+        .quad   0x1065aae50d8cc5bb
+        .quad   0x1c2c4525df200d57
+        .quad   0x5c3b2dd6bfca674a
+        .quad   0x0a07e7b1e1834030
+        .quad   0x69a198e64f1ce716
+
+        // 2^100 * 1 * B
+
+        .quad   0x7afcd613efa9d697
+        .quad   0x0cc45aa41c067959
+        .quad   0xa56fe104c1fada96
+        .quad   0x3a73b70472e40365
+        .quad   0x7b26e56b9e2d4734
+        .quad   0xc4c7132b81c61675
+        .quad   0xef5c9525ec9cde7f
+        .quad   0x39c80b16e71743ad
+        .quad   0x0f196e0d1b826c68
+        .quad   0xf71ff0e24960e3db
+        .quad   0x6113167023b7436c
+        .quad   0x0cf0ea5877da7282
+
+        // 2^100 * 2 * B
+
+        .quad   0x196c80a4ddd4ccbd
+        .quad   0x22e6f55d95f2dd9d
+        .quad   0xc75e33c740d6c71b
+        .quad   0x7bb51279cb3c042f
+        .quad   0xe332ced43ba6945a
+        .quad   0xde0b1361e881c05d
+        .quad   0x1ad40f095e67ed3b
+        .quad   0x5da8acdab8c63d5d
+        .quad   0xc4b6664a3a70159f
+        .quad   0x76194f0f0a904e14
+        .quad   0xa5614c39a4096c13
+        .quad   0x6cd0ff50979feced
+
+        // 2^100 * 3 * B
+
+        .quad   0xc0e067e78f4428ac
+        .quad   0x14835ab0a61135e3
+        .quad   0xf21d14f338062935
+        .quad   0x6390a4c8df04849c
+        .quad   0x7fecfabdb04ba18e
+        .quad   0xd0fc7bfc3bddbcf7
+        .quad   0xa41d486e057a131c
+        .quad   0x641a4391f2223a61
+        .quad   0xc5c6b95aa606a8db
+        .quad   0x914b7f9eb06825f1
+        .quad   0x2a731f6b44fc9eff
+        .quad   0x30ddf38562705cfc
+
+        // 2^100 * 4 * B
+
+        .quad   0x4e3dcbdad1bff7f9
+        .quad   0xc9118e8220645717
+        .quad   0xbacccebc0f189d56
+        .quad   0x1b4822e9d4467668
+        .quad   0x33bef2bd68bcd52c
+        .quad   0xc649dbb069482ef2
+        .quad   0xb5b6ee0c41cb1aee
+        .quad   0x5c294d270212a7e5
+        .quad   0xab360a7f25563781
+        .quad   0x2512228a480f7958
+        .quad   0xc75d05276114b4e3
+        .quad   0x222d9625d976fe2a
+
+        // 2^100 * 5 * B
+
+        .quad   0x1c717f85b372ace1
+        .quad   0x81930e694638bf18
+        .quad   0x239cad056bc08b58
+        .quad   0x0b34271c87f8fff4
+        .quad   0x0f94be7e0a344f85
+        .quad   0xeb2faa8c87f22c38
+        .quad   0x9ce1e75e4ee16f0f
+        .quad   0x43e64e5418a08dea
+        .quad   0x8155e2521a35ce63
+        .quad   0xbe100d4df912028e
+        .quad   0xbff80bf8a57ddcec
+        .quad   0x57342dc96d6bc6e4
+
+        // 2^100 * 6 * B
+
+        .quad   0xefeef065c8ce5998
+        .quad   0xbf029510b5cbeaa2
+        .quad   0x8c64a10620b7c458
+        .quad   0x35134fb231c24855
+        .quad   0xf3c3bcb71e707bf6
+        .quad   0x351d9b8c7291a762
+        .quad   0x00502e6edad69a33
+        .quad   0x522f521f1ec8807f
+        .quad   0x272c1f46f9a3902b
+        .quad   0xc91ba3b799657bcc
+        .quad   0xae614b304f8a1c0e
+        .quad   0x7afcaad70b99017b
+
+        // 2^100 * 7 * B
+
+        .quad   0xc25ded54a4b8be41
+        .quad   0x902d13e11bb0e2dd
+        .quad   0x41f43233cde82ab2
+        .quad   0x1085faa5c3aae7cb
+        .quad   0xa88141ecef842b6b
+        .quad   0x55e7b14797abe6c5
+        .quad   0x8c748f9703784ffe
+        .quad   0x5b50a1f7afcd00b7
+        .quad   0x9b840f66f1361315
+        .quad   0x18462242701003e9
+        .quad   0x65ed45fae4a25080
+        .quad   0x0a2862393fda7320
+
+        // 2^100 * 8 * B
+
+        .quad   0x46ab13c8347cbc9d
+        .quad   0x3849e8d499c12383
+        .quad   0x4cea314087d64ac9
+        .quad   0x1f354134b1a29ee7
+        .quad   0x960e737b6ecb9d17
+        .quad   0xfaf24948d67ceae1
+        .quad   0x37e7a9b4d55e1b89
+        .quad   0x5cb7173cb46c59eb
+        .quad   0x4a89e68b82b7abf0
+        .quad   0xf41cd9279ba6b7b9
+        .quad   0x16e6c210e18d876f
+        .quad   0x7cacdb0f7f1b09c6
+
+        // 2^104 * 1 * B
+
+        .quad   0x9062b2e0d91a78bc
+        .quad   0x47c9889cc8509667
+        .quad   0x9df54a66405070b8
+        .quad   0x7369e6a92493a1bf
+        .quad   0xe1014434dcc5caed
+        .quad   0x47ed5d963c84fb33
+        .quad   0x70019576ed86a0e7
+        .quad   0x25b2697bd267f9e4
+        .quad   0x9d673ffb13986864
+        .quad   0x3ca5fbd9415dc7b8
+        .quad   0xe04ecc3bdf273b5e
+        .quad   0x1420683db54e4cd2
+
+        // 2^104 * 2 * B
+
+        .quad   0xb478bd1e249dd197
+        .quad   0x620c35005e58c102
+        .quad   0xfb02d32fccbaac5c
+        .quad   0x60b63bebf508a72d
+        .quad   0x34eebb6fc1cc5ad0
+        .quad   0x6a1b0ce99646ac8b
+        .quad   0xd3b0da49a66bde53
+        .quad   0x31e83b4161d081c1
+        .quad   0x97e8c7129e062b4f
+        .quad   0x49e48f4f29320ad8
+        .quad   0x5bece14b6f18683f
+        .quad   0x55cf1eb62d550317
+
+        // 2^104 * 3 * B
+
+        .quad   0x5879101065c23d58
+        .quad   0x8b9d086d5094819c
+        .quad   0xe2402fa912c55fa7
+        .quad   0x669a6564570891d4
+        .quad   0x3076b5e37df58c52
+        .quad   0xd73ab9dde799cc36
+        .quad   0xbd831ce34913ee20
+        .quad   0x1a56fbaa62ba0133
+        .quad   0x943e6b505c9dc9ec
+        .quad   0x302557bba77c371a
+        .quad   0x9873ae5641347651
+        .quad   0x13c4836799c58a5c
+
+        // 2^104 * 4 * B
+
+        .quad   0x423a5d465ab3e1b9
+        .quad   0xfc13c187c7f13f61
+        .quad   0x19f83664ecb5b9b6
+        .quad   0x66f80c93a637b607
+        .quad   0xc4dcfb6a5d8bd080
+        .quad   0xdeebc4ec571a4842
+        .quad   0xd4b2e883b8e55365
+        .quad   0x50bdc87dc8e5b827
+        .quad   0x606d37836edfe111
+        .quad   0x32353e15f011abd9
+        .quad   0x64b03ac325b73b96
+        .quad   0x1dd56444725fd5ae
+
+        // 2^104 * 5 * B
+
+        .quad   0x8fa47ff83362127d
+        .quad   0xbc9f6ac471cd7c15
+        .quad   0x6e71454349220c8b
+        .quad   0x0e645912219f732e
+        .quad   0xc297e60008bac89a
+        .quad   0x7d4cea11eae1c3e0
+        .quad   0xf3e38be19fe7977c
+        .quad   0x3a3a450f63a305cd
+        .quad   0x078f2f31d8394627
+        .quad   0x389d3183de94a510
+        .quad   0xd1e36c6d17996f80
+        .quad   0x318c8d9393a9a87b
+
+        // 2^104 * 6 * B
+
+        .quad   0xf2745d032afffe19
+        .quad   0x0c9f3c497f24db66
+        .quad   0xbc98d3e3ba8598ef
+        .quad   0x224c7c679a1d5314
+        .quad   0x5d669e29ab1dd398
+        .quad   0xfc921658342d9e3b
+        .quad   0x55851dfdf35973cd
+        .quad   0x509a41c325950af6
+        .quad   0xbdc06edca6f925e9
+        .quad   0x793ef3f4641b1f33
+        .quad   0x82ec12809d833e89
+        .quad   0x05bff02328a11389
+
+        // 2^104 * 7 * B
+
+        .quad   0x3632137023cae00b
+        .quad   0x544acf0ad1accf59
+        .quad   0x96741049d21a1c88
+        .quad   0x780b8cc3fa2a44a7
+        .quad   0x6881a0dd0dc512e4
+        .quad   0x4fe70dc844a5fafe
+        .quad   0x1f748e6b8f4a5240
+        .quad   0x576277cdee01a3ea
+        .quad   0x1ef38abc234f305f
+        .quad   0x9a577fbd1405de08
+        .quad   0x5e82a51434e62a0d
+        .quad   0x5ff418726271b7a1
+
+        // 2^104 * 8 * B
+
+        .quad   0x398e080c1789db9d
+        .quad   0xa7602025f3e778f5
+        .quad   0xfa98894c06bd035d
+        .quad   0x106a03dc25a966be
+        .quad   0xe5db47e813b69540
+        .quad   0xf35d2a3b432610e1
+        .quad   0xac1f26e938781276
+        .quad   0x29d4db8ca0a0cb69
+        .quad   0xd9ad0aaf333353d0
+        .quad   0x38669da5acd309e5
+        .quad   0x3c57658ac888f7f0
+        .quad   0x4ab38a51052cbefa
+
+        // 2^108 * 1 * B
+
+        .quad   0xdfdacbee4324c0e9
+        .quad   0x054442883f955bb7
+        .quad   0xdef7aaa8ea31609f
+        .quad   0x68aee70642287cff
+        .quad   0xf68fe2e8809de054
+        .quad   0xe3bc096a9c82bad1
+        .quad   0x076353d40aadbf45
+        .quad   0x7b9b1fb5dea1959e
+        .quad   0xf01cc8f17471cc0c
+        .quad   0x95242e37579082bb
+        .quad   0x27776093d3e46b5f
+        .quad   0x2d13d55a28bd85fb
+
+        // 2^108 * 2 * B
+
+        .quad   0xfac5d2065b35b8da
+        .quad   0xa8da8a9a85624bb7
+        .quad   0xccd2ca913d21cd0f
+        .quad   0x6b8341ee8bf90d58
+        .quad   0xbf019cce7aee7a52
+        .quad   0xa8ded2b6e454ead3
+        .quad   0x3c619f0b87a8bb19
+        .quad   0x3619b5d7560916d8
+        .quad   0x3579f26b0282c4b2
+        .quad   0x64d592f24fafefae
+        .quad   0xb7cded7b28c8c7c0
+        .quad   0x6a927b6b7173a8d7
+
+        // 2^108 * 3 * B
+
+        .quad   0x1f6db24f986e4656
+        .quad   0x1021c02ed1e9105b
+        .quad   0xf8ff3fff2cc0a375
+        .quad   0x1d2a6bf8c6c82592
+        .quad   0x8d7040863ece88eb
+        .quad   0xf0e307a980eec08c
+        .quad   0xac2250610d788fda
+        .quad   0x056d92a43a0d478d
+        .quad   0x1b05a196fc3da5a1
+        .quad   0x77d7a8c243b59ed0
+        .quad   0x06da3d6297d17918
+        .quad   0x66fbb494f12353f7
+
+        // 2^108 * 4 * B
+
+        .quad   0x751a50b9d85c0fb8
+        .quad   0xd1afdc258bcf097b
+        .quad   0x2f16a6a38309a969
+        .quad   0x14ddff9ee5b00659
+        .quad   0xd6d70996f12309d6
+        .quad   0xdbfb2385e9c3d539
+        .quad   0x46d602b0f7552411
+        .quad   0x270a0b0557843e0c
+        .quad   0x61ff0640a7862bcc
+        .quad   0x81cac09a5f11abfe
+        .quad   0x9047830455d12abb
+        .quad   0x19a4bde1945ae873
+
+        // 2^108 * 5 * B
+
+        .quad   0x9b9f26f520a6200a
+        .quad   0x64804443cf13eaf8
+        .quad   0x8a63673f8631edd3
+        .quad   0x72bbbce11ed39dc1
+        .quad   0x40c709dec076c49f
+        .quad   0x657bfaf27f3e53f6
+        .quad   0x40662331eca042c4
+        .quad   0x14b375487eb4df04
+        .quad   0xae853c94ab66dc47
+        .quad   0xeb62343edf762d6e
+        .quad   0xf08e0e186fb2f7d1
+        .quad   0x4f0b1c02700ab37a
+
+        // 2^108 * 6 * B
+
+        .quad   0xe1706787d81951fa
+        .quad   0xa10a2c8eb290c77b
+        .quad   0xe7382fa03ed66773
+        .quad   0x0a4d84710bcc4b54
+        .quad   0x79fd21ccc1b2e23f
+        .quad   0x4ae7c281453df52a
+        .quad   0xc8172ec9d151486b
+        .quad   0x68abe9443e0a7534
+        .quad   0xda12c6c407831dcb
+        .quad   0x0da230d74d5c510d
+        .quad   0x4ab1531e6bd404e1
+        .quad   0x4106b166bcf440ef
+
+        // 2^108 * 7 * B
+
+        .quad   0x02e57a421cd23668
+        .quad   0x4ad9fb5d0eaef6fd
+        .quad   0x954e6727b1244480
+        .quad   0x7f792f9d2699f331
+        .quad   0xa485ccd539e4ecf2
+        .quad   0x5aa3f3ad0555bab5
+        .quad   0x145e3439937df82d
+        .quad   0x1238b51e1214283f
+        .quad   0x0b886b925fd4d924
+        .quad   0x60906f7a3626a80d
+        .quad   0xecd367b4b98abd12
+        .quad   0x2876beb1def344cf
+
+        // 2^108 * 8 * B
+
+        .quad   0xdc84e93563144691
+        .quad   0x632fe8a0d61f23f4
+        .quad   0x4caa800612a9a8d5
+        .quad   0x48f9dbfa0e9918d3
+        .quad   0xd594b3333a8a85f8
+        .quad   0x4ea37689e78d7d58
+        .quad   0x73bf9f455e8e351f
+        .quad   0x5507d7d2bc41ebb4
+        .quad   0x1ceb2903299572fc
+        .quad   0x7c8ccaa29502d0ee
+        .quad   0x91bfa43411cce67b
+        .quad   0x5784481964a831e7
+
+        // 2^112 * 1 * B
+
+        .quad   0xda7c2b256768d593
+        .quad   0x98c1c0574422ca13
+        .quad   0xf1a80bd5ca0ace1d
+        .quad   0x29cdd1adc088a690
+        .quad   0xd6cfd1ef5fddc09c
+        .quad   0xe82b3efdf7575dce
+        .quad   0x25d56b5d201634c2
+        .quad   0x3041c6bb04ed2b9b
+        .quad   0x0ff2f2f9d956e148
+        .quad   0xade797759f356b2e
+        .quad   0x1a4698bb5f6c025c
+        .quad   0x104bbd6814049a7b
+
+        // 2^112 * 2 * B
+
+        .quad   0x51f0fd3168f1ed67
+        .quad   0x2c811dcdd86f3bc2
+        .quad   0x44dc5c4304d2f2de
+        .quad   0x5be8cc57092a7149
+        .quad   0xa95d9a5fd67ff163
+        .quad   0xe92be69d4cc75681
+        .quad   0xb7f8024cde20f257
+        .quad   0x204f2a20fb072df5
+        .quad   0xc8143b3d30ebb079
+        .quad   0x7589155abd652e30
+        .quad   0x653c3c318f6d5c31
+        .quad   0x2570fb17c279161f
+
+        // 2^112 * 3 * B
+
+        .quad   0x3efa367f2cb61575
+        .quad   0xf5f96f761cd6026c
+        .quad   0xe8c7142a65b52562
+        .quad   0x3dcb65ea53030acd
+        .quad   0x192ea9550bb8245a
+        .quad   0xc8e6fba88f9050d1
+        .quad   0x7986ea2d88a4c935
+        .quad   0x241c5f91de018668
+        .quad   0x28d8172940de6caa
+        .quad   0x8fbf2cf022d9733a
+        .quad   0x16d7fcdd235b01d1
+        .quad   0x08420edd5fcdf0e5
+
+        // 2^112 * 4 * B
+
+        .quad   0xcdff20ab8362fa4a
+        .quad   0x57e118d4e21a3e6e
+        .quad   0xe3179617fc39e62b
+        .quad   0x0d9a53efbc1769fd
+        .quad   0x0358c34e04f410ce
+        .quad   0xb6135b5a276e0685
+        .quad   0x5d9670c7ebb91521
+        .quad   0x04d654f321db889c
+        .quad   0x5e7dc116ddbdb5d5
+        .quad   0x2954deb68da5dd2d
+        .quad   0x1cb608173334a292
+        .quad   0x4a7a4f2618991ad7
+
+        // 2^112 * 5 * B
+
+        .quad   0xf4a718025fb15f95
+        .quad   0x3df65f346b5c1b8f
+        .quad   0xcdfcf08500e01112
+        .quad   0x11b50c4cddd31848
+        .quad   0x24c3b291af372a4b
+        .quad   0x93da8270718147f2
+        .quad   0xdd84856486899ef2
+        .quad   0x4a96314223e0ee33
+        .quad   0xa6e8274408a4ffd6
+        .quad   0x738e177e9c1576d9
+        .quad   0x773348b63d02b3f2
+        .quad   0x4f4bce4dce6bcc51
+
+        // 2^112 * 6 * B
+
+        .quad   0xa71fce5ae2242584
+        .quad   0x26ea725692f58a9e
+        .quad   0xd21a09d71cea3cf4
+        .quad   0x73fcdd14b71c01e6
+        .quad   0x30e2616ec49d0b6f
+        .quad   0xe456718fcaec2317
+        .quad   0x48eb409bf26b4fa6
+        .quad   0x3042cee561595f37
+        .quad   0x427e7079449bac41
+        .quad   0x855ae36dbce2310a
+        .quad   0x4cae76215f841a7c
+        .quad   0x389e740c9a9ce1d6
+
+        // 2^112 * 7 * B
+
+        .quad   0x64fcb3ae34dcb9ce
+        .quad   0x97500323e348d0ad
+        .quad   0x45b3f07d62c6381b
+        .quad   0x61545379465a6788
+        .quad   0xc9bd78f6570eac28
+        .quad   0xe55b0b3227919ce1
+        .quad   0x65fc3eaba19b91ed
+        .quad   0x25c425e5d6263690
+        .quad   0x3f3e06a6f1d7de6e
+        .quad   0x3ef976278e062308
+        .quad   0x8c14f6264e8a6c77
+        .quad   0x6539a08915484759
+
+        // 2^112 * 8 * B
+
+        .quad   0xe9d21f74c3d2f773
+        .quad   0xc150544125c46845
+        .quad   0x624e5ce8f9b99e33
+        .quad   0x11c5e4aac5cd186c
+        .quad   0xddc4dbd414bb4a19
+        .quad   0x19b2bc3c98424f8e
+        .quad   0x48a89fd736ca7169
+        .quad   0x0f65320ef019bd90
+        .quad   0xd486d1b1cafde0c6
+        .quad   0x4f3fe6e3163b5181
+        .quad   0x59a8af0dfaf2939a
+        .quad   0x4cabc7bdec33072a
+
+        // 2^116 * 1 * B
+
+        .quad   0x16faa8fb532f7428
+        .quad   0xdbd42ea046a4e272
+        .quad   0x5337653b8b9ea480
+        .quad   0x4065947223973f03
+        .quad   0xf7c0a19c1a54a044
+        .quad   0x4a1c5e2477bd9fbb
+        .quad   0xa6e3ca115af22972
+        .quad   0x1819bb953f2e9e0d
+        .quad   0x498fbb795e042e84
+        .quad   0x7d0dd89a7698b714
+        .quad   0x8bfb0ba427fe6295
+        .quad   0x36ba82e721200524
+
+        // 2^116 * 2 * B
+
+        .quad   0xd60ecbb74245ec41
+        .quad   0xfd9be89e34348716
+        .quad   0xc9240afee42284de
+        .quad   0x4472f648d0531db4
+        .quad   0xc8d69d0a57274ed5
+        .quad   0x45ba803260804b17
+        .quad   0xdf3cda102255dfac
+        .quad   0x77d221232709b339
+        .quad   0x498a6d7064ad94d8
+        .quad   0xa5b5c8fd9af62263
+        .quad   0x8ca8ed0545c141f4
+        .quad   0x2c63bec3662d358c
+
+        // 2^116 * 3 * B
+
+        .quad   0x7fe60d8bea787955
+        .quad   0xb9dc117eb5f401b7
+        .quad   0x91c7c09a19355cce
+        .quad   0x22692ef59442bedf
+        .quad   0x9a518b3a8586f8bf
+        .quad   0x9ee71af6cbb196f0
+        .quad   0xaa0625e6a2385cf2
+        .quad   0x1deb2176ddd7c8d1
+        .quad   0x8563d19a2066cf6c
+        .quad   0x401bfd8c4dcc7cd7
+        .quad   0xd976a6becd0d8f62
+        .quad   0x67cfd773a278b05e
+
+        // 2^116 * 4 * B
+
+        .quad   0x8dec31faef3ee475
+        .quad   0x99dbff8a9e22fd92
+        .quad   0x512d11594e26cab1
+        .quad   0x0cde561eec4310b9
+        .quad   0x2d5fa9855a4e586a
+        .quad   0x65f8f7a449beab7e
+        .quad   0xaa074dddf21d33d3
+        .quad   0x185cba721bcb9dee
+        .quad   0x93869da3f4e3cb41
+        .quad   0xbf0392f540f7977e
+        .quad   0x026204fcd0463b83
+        .quad   0x3ec91a769eec6eed
+
+        // 2^116 * 5 * B
+
+        .quad   0x1e9df75bf78166ad
+        .quad   0x4dfda838eb0cd7af
+        .quad   0xba002ed8c1eaf988
+        .quad   0x13fedb3e11f33cfc
+        .quad   0x0fad2fb7b0a3402f
+        .quad   0x46615ecbfb69f4a8
+        .quad   0xf745bcc8c5f8eaa6
+        .quad   0x7a5fa8794a94e896
+        .quad   0x52958faa13cd67a1
+        .quad   0x965ee0818bdbb517
+        .quad   0x16e58daa2e8845b3
+        .quad   0x357d397d5499da8f
+
+        // 2^116 * 6 * B
+
+        .quad   0x1ebfa05fb0bace6c
+        .quad   0xc934620c1caf9a1e
+        .quad   0xcc771cc41d82b61a
+        .quad   0x2d94a16aa5f74fec
+        .quad   0x481dacb4194bfbf8
+        .quad   0x4d77e3f1bae58299
+        .quad   0x1ef4612e7d1372a0
+        .quad   0x3a8d867e70ff69e1
+        .quad   0x6f58cd5d55aff958
+        .quad   0xba3eaa5c75567721
+        .quad   0x75c123999165227d
+        .quad   0x69be1343c2f2b35e
+
+        // 2^116 * 7 * B
+
+        .quad   0x0e091d5ee197c92a
+        .quad   0x4f51019f2945119f
+        .quad   0x143679b9f034e99c
+        .quad   0x7d88112e4d24c696
+        .quad   0x82bbbdac684b8de3
+        .quad   0xa2f4c7d03fca0718
+        .quad   0x337f92fbe096aaa8
+        .quad   0x200d4d8c63587376
+        .quad   0x208aed4b4893b32b
+        .quad   0x3efbf23ebe59b964
+        .quad   0xd762deb0dba5e507
+        .quad   0x69607bd681bd9d94
+
+        // 2^116 * 8 * B
+
+        .quad   0xf6be021068de1ce1
+        .quad   0xe8d518e70edcbc1f
+        .quad   0xe3effdd01b5505a5
+        .quad   0x35f63353d3ec3fd0
+        .quad   0x3b7f3bd49323a902
+        .quad   0x7c21b5566b2c6e53
+        .quad   0xe5ba8ff53a7852a7
+        .quad   0x28bc77a5838ece00
+        .quad   0x63ba78a8e25d8036
+        .quad   0x63651e0094333490
+        .quad   0x48d82f20288ce532
+        .quad   0x3a31abfa36b57524
+
+        // 2^120 * 1 * B
+
+        .quad   0x239e9624089c0a2e
+        .quad   0xc748c4c03afe4738
+        .quad   0x17dbed2a764fa12a
+        .quad   0x639b93f0321c8582
+        .quad   0xc08f788f3f78d289
+        .quad   0xfe30a72ca1404d9f
+        .quad   0xf2778bfccf65cc9d
+        .quad   0x7ee498165acb2021
+        .quad   0x7bd508e39111a1c3
+        .quad   0x2b2b90d480907489
+        .quad   0xe7d2aec2ae72fd19
+        .quad   0x0edf493c85b602a6
+
+        // 2^120 * 2 * B
+
+        .quad   0xaecc8158599b5a68
+        .quad   0xea574f0febade20e
+        .quad   0x4fe41d7422b67f07
+        .quad   0x403b92e3019d4fb4
+        .quad   0x6767c4d284764113
+        .quad   0xa090403ff7f5f835
+        .quad   0x1c8fcffacae6bede
+        .quad   0x04c00c54d1dfa369
+        .quad   0x4dc22f818b465cf8
+        .quad   0x71a0f35a1480eff8
+        .quad   0xaee8bfad04c7d657
+        .quad   0x355bb12ab26176f4
+
+        // 2^120 * 3 * B
+
+        .quad   0xa71e64cc7493bbf4
+        .quad   0xe5bd84d9eca3b0c3
+        .quad   0x0a6bc50cfa05e785
+        .quad   0x0f9b8132182ec312
+        .quad   0xa301dac75a8c7318
+        .quad   0xed90039db3ceaa11
+        .quad   0x6f077cbf3bae3f2d
+        .quad   0x7518eaf8e052ad8e
+        .quad   0xa48859c41b7f6c32
+        .quad   0x0f2d60bcf4383298
+        .quad   0x1815a929c9b1d1d9
+        .quad   0x47c3871bbb1755c4
+
+        // 2^120 * 4 * B
+
+        .quad   0x5144539771ec4f48
+        .quad   0xf805b17dc98c5d6e
+        .quad   0xf762c11a47c3c66b
+        .quad   0x00b89b85764699dc
+        .quad   0xfbe65d50c85066b0
+        .quad   0x62ecc4b0b3a299b0
+        .quad   0xe53754ea441ae8e0
+        .quad   0x08fea02ce8d48d5f
+        .quad   0x824ddd7668deead0
+        .quad   0xc86445204b685d23
+        .quad   0xb514cfcd5d89d665
+        .quad   0x473829a74f75d537
+
+        // 2^120 * 5 * B
+
+        .quad   0x82d2da754679c418
+        .quad   0xe63bd7d8b2618df0
+        .quad   0x355eef24ac47eb0a
+        .quad   0x2078684c4833c6b4
+        .quad   0x23d9533aad3902c9
+        .quad   0x64c2ddceef03588f
+        .quad   0x15257390cfe12fb4
+        .quad   0x6c668b4d44e4d390
+        .quad   0x3b48cf217a78820c
+        .quad   0xf76a0ab281273e97
+        .quad   0xa96c65a78c8eed7b
+        .quad   0x7411a6054f8a433f
+
+        // 2^120 * 6 * B
+
+        .quad   0x4d659d32b99dc86d
+        .quad   0x044cdc75603af115
+        .quad   0xb34c712cdcc2e488
+        .quad   0x7c136574fb8134ff
+        .quad   0x579ae53d18b175b4
+        .quad   0x68713159f392a102
+        .quad   0x8455ecba1eef35f5
+        .quad   0x1ec9a872458c398f
+        .quad   0xb8e6a4d400a2509b
+        .quad   0x9b81d7020bc882b4
+        .quad   0x57e7cc9bf1957561
+        .quad   0x3add88a5c7cd6460
+
+        // 2^120 * 7 * B
+
+        .quad   0xab895770b635dcf2
+        .quad   0x02dfef6cf66c1fbc
+        .quad   0x85530268beb6d187
+        .quad   0x249929fccc879e74
+        .quad   0x85c298d459393046
+        .quad   0x8f7e35985ff659ec
+        .quad   0x1d2ca22af2f66e3a
+        .quad   0x61ba1131a406a720
+        .quad   0xa3d0a0f116959029
+        .quad   0x023b6b6cba7ebd89
+        .quad   0x7bf15a3e26783307
+        .quad   0x5620310cbbd8ece7
+
+        // 2^120 * 8 * B
+
+        .quad   0x528993434934d643
+        .quad   0xb9dbf806a51222f5
+        .quad   0x8f6d878fc3f41c22
+        .quad   0x37676a2a4d9d9730
+        .quad   0x6646b5f477e285d6
+        .quad   0x40e8ff676c8f6193
+        .quad   0xa6ec7311abb594dd
+        .quad   0x7ec846f3658cec4d
+        .quad   0x9b5e8f3f1da22ec7
+        .quad   0x130f1d776c01cd13
+        .quad   0x214c8fcfa2989fb8
+        .quad   0x6daaf723399b9dd5
+
+        // 2^124 * 1 * B
+
+        .quad   0x591e4a5610628564
+        .quad   0x2a4bb87ca8b4df34
+        .quad   0xde2a2572e7a38e43
+        .quad   0x3cbdabd9fee5046e
+        .quad   0x81aebbdd2cd13070
+        .quad   0x962e4325f85a0e9e
+        .quad   0xde9391aacadffecb
+        .quad   0x53177fda52c230e6
+        .quad   0xa7bc970650b9de79
+        .quad   0x3d12a7fbc301b59b
+        .quad   0x02652e68d36ae38c
+        .quad   0x79d739835a6199dc
+
+        // 2^124 * 2 * B
+
+        .quad   0xd9354df64131c1bd
+        .quad   0x758094a186ec5822
+        .quad   0x4464ee12e459f3c2
+        .quad   0x6c11fce4cb133282
+        .quad   0x21c9d9920d591737
+        .quad   0x9bea41d2e9b46cd6
+        .quad   0xe20e84200d89bfca
+        .quad   0x79d99f946eae5ff8
+        .quad   0xf17b483568673205
+        .quad   0x387deae83caad96c
+        .quad   0x61b471fd56ffe386
+        .quad   0x31741195b745a599
+
+        // 2^124 * 3 * B
+
+        .quad   0xe8d10190b77a360b
+        .quad   0x99b983209995e702
+        .quad   0xbd4fdff8fa0247aa
+        .quad   0x2772e344e0d36a87
+        .quad   0x17f8ba683b02a047
+        .quad   0x50212096feefb6c8
+        .quad   0x70139be21556cbe2
+        .quad   0x203e44a11d98915b
+        .quad   0xd6863eba37b9e39f
+        .quad   0x105bc169723b5a23
+        .quad   0x104f6459a65c0762
+        .quad   0x567951295b4d38d4
+
+        // 2^124 * 4 * B
+
+        .quad   0x535fd60613037524
+        .quad   0xe210adf6b0fbc26a
+        .quad   0xac8d0a9b23e990ae
+        .quad   0x47204d08d72fdbf9
+        .quad   0x07242eb30d4b497f
+        .quad   0x1ef96306b9bccc87
+        .quad   0x37950934d8116f45
+        .quad   0x05468d6201405b04
+        .quad   0x00f565a9f93267de
+        .quad   0xcecfd78dc0d58e8a
+        .quad   0xa215e2dcf318e28e
+        .quad   0x4599ee919b633352
+
+        // 2^124 * 5 * B
+
+        .quad   0xd3c220ca70e0e76b
+        .quad   0xb12bea58ea9f3094
+        .quad   0x294ddec8c3271282
+        .quad   0x0c3539e1a1d1d028
+        .quad   0xac746d6b861ae579
+        .quad   0x31ab0650f6aea9dc
+        .quad   0x241d661140256d4c
+        .quad   0x2f485e853d21a5de
+        .quad   0x329744839c0833f3
+        .quad   0x6fe6257fd2abc484
+        .quad   0x5327d1814b358817
+        .quad   0x65712585893fe9bc
+
+        // 2^124 * 6 * B
+
+        .quad   0x9c102fb732a61161
+        .quad   0xe48e10dd34d520a8
+        .quad   0x365c63546f9a9176
+        .quad   0x32f6fe4c046f6006
+        .quad   0x81c29f1bd708ee3f
+        .quad   0xddcb5a05ae6407d0
+        .quad   0x97aec1d7d2a3eba7
+        .quad   0x1590521a91d50831
+        .quad   0x40a3a11ec7910acc
+        .quad   0x9013dff8f16d27ae
+        .quad   0x1a9720d8abb195d4
+        .quad   0x1bb9fe452ea98463
+
+        // 2^124 * 7 * B
+
+        .quad   0xe9d1d950b3d54f9e
+        .quad   0x2d5f9cbee00d33c1
+        .quad   0x51c2c656a04fc6ac
+        .quad   0x65c091ee3c1cbcc9
+        .quad   0xcf5e6c95cc36747c
+        .quad   0x294201536b0bc30d
+        .quad   0x453ac67cee797af0
+        .quad   0x5eae6ab32a8bb3c9
+        .quad   0x7083661114f118ea
+        .quad   0x2b37b87b94349cad
+        .quad   0x7273f51cb4e99f40
+        .quad   0x78a2a95823d75698
+
+        // 2^124 * 8 * B
+
+        .quad   0xa2b072e95c8c2ace
+        .quad   0x69cffc96651e9c4b
+        .quad   0x44328ef842e7b42b
+        .quad   0x5dd996c122aadeb3
+        .quad   0xb4f23c425ef83207
+        .quad   0xabf894d3c9a934b5
+        .quad   0xd0708c1339fd87f7
+        .quad   0x1876789117166130
+        .quad   0x925b5ef0670c507c
+        .quad   0x819bc842b93c33bf
+        .quad   0x10792e9a70dd003f
+        .quad   0x59ad4b7a6e28dc74
+
+        // 2^128 * 1 * B
+
+        .quad   0x5f3a7562eb3dbe47
+        .quad   0xf7ea38548ebda0b8
+        .quad   0x00c3e53145747299
+        .quad   0x1304e9e71627d551
+        .quad   0x583b04bfacad8ea2
+        .quad   0x29b743e8148be884
+        .quad   0x2b1e583b0810c5db
+        .quad   0x2b5449e58eb3bbaa
+        .quad   0x789814d26adc9cfe
+        .quad   0x3c1bab3f8b48dd0b
+        .quad   0xda0fe1fff979c60a
+        .quad   0x4468de2d7c2dd693
+
+        // 2^128 * 2 * B
+
+        .quad   0x51bb355e9419469e
+        .quad   0x33e6dc4c23ddc754
+        .quad   0x93a5b6d6447f9962
+        .quad   0x6cce7c6ffb44bd63
+        .quad   0x4b9ad8c6f86307ce
+        .quad   0x21113531435d0c28
+        .quad   0xd4a866c5657a772c
+        .quad   0x5da6427e63247352
+        .quad   0x1a94c688deac22ca
+        .quad   0xb9066ef7bbae1ff8
+        .quad   0x88ad8c388d59580f
+        .quad   0x58f29abfe79f2ca8
+
+        // 2^128 * 3 * B
+
+        .quad   0xe90ecfab8de73e68
+        .quad   0x54036f9f377e76a5
+        .quad   0xf0495b0bbe015982
+        .quad   0x577629c4a7f41e36
+        .quad   0x4b5a64bf710ecdf6
+        .quad   0xb14ce538462c293c
+        .quad   0x3643d056d50b3ab9
+        .quad   0x6af93724185b4870
+        .quad   0x3220024509c6a888
+        .quad   0xd2e036134b558973
+        .quad   0x83e236233c33289f
+        .quad   0x701f25bb0caec18f
+
+        // 2^128 * 4 * B
+
+        .quad   0xc3a8b0f8e4616ced
+        .quad   0xf700660e9e25a87d
+        .quad   0x61e3061ff4bca59c
+        .quad   0x2e0c92bfbdc40be9
+        .quad   0x9d18f6d97cbec113
+        .quad   0x844a06e674bfdbe4
+        .quad   0x20f5b522ac4e60d6
+        .quad   0x720a5bc050955e51
+        .quad   0x0c3f09439b805a35
+        .quad   0xe84e8b376242abfc
+        .quad   0x691417f35c229346
+        .quad   0x0e9b9cbb144ef0ec
+
+        // 2^128 * 5 * B
+
+        .quad   0xfbbad48ffb5720ad
+        .quad   0xee81916bdbf90d0e
+        .quad   0xd4813152635543bf
+        .quad   0x221104eb3f337bd8
+        .quad   0x8dee9bd55db1beee
+        .quad   0xc9c3ab370a723fb9
+        .quad   0x44a8f1bf1c68d791
+        .quad   0x366d44191cfd3cde
+        .quad   0x9e3c1743f2bc8c14
+        .quad   0x2eda26fcb5856c3b
+        .quad   0xccb82f0e68a7fb97
+        .quad   0x4167a4e6bc593244
+
+        // 2^128 * 6 * B
+
+        .quad   0x643b9d2876f62700
+        .quad   0x5d1d9d400e7668eb
+        .quad   0x1b4b430321fc0684
+        .quad   0x7938bb7e2255246a
+        .quad   0xc2be2665f8ce8fee
+        .quad   0xe967ff14e880d62c
+        .quad   0xf12e6e7e2f364eee
+        .quad   0x34b33370cb7ed2f6
+        .quad   0xcdc591ee8681d6cc
+        .quad   0xce02109ced85a753
+        .quad   0xed7485c158808883
+        .quad   0x1176fc6e2dfe65e4
+
+        // 2^128 * 7 * B
+
+        .quad   0xb4af6cd05b9c619b
+        .quad   0x2ddfc9f4b2a58480
+        .quad   0x3d4fa502ebe94dc4
+        .quad   0x08fc3a4c677d5f34
+        .quad   0xdb90e28949770eb8
+        .quad   0x98fbcc2aacf440a3
+        .quad   0x21354ffeded7879b
+        .quad   0x1f6a3e54f26906b6
+        .quad   0x60a4c199d30734ea
+        .quad   0x40c085b631165cd6
+        .quad   0xe2333e23f7598295
+        .quad   0x4f2fad0116b900d1
+
+        // 2^128 * 8 * B
+
+        .quad   0x44beb24194ae4e54
+        .quad   0x5f541c511857ef6c
+        .quad   0xa61e6b2d368d0498
+        .quad   0x445484a4972ef7ab
+        .quad   0x962cd91db73bb638
+        .quad   0xe60577aafc129c08
+        .quad   0x6f619b39f3b61689
+        .quad   0x3451995f2944ee81
+        .quad   0x9152fcd09fea7d7c
+        .quad   0x4a816c94b0935cf6
+        .quad   0x258e9aaa47285c40
+        .quad   0x10b89ca6042893b7
+
+        // 2^132 * 1 * B
+
+        .quad   0x9b2a426e3b646025
+        .quad   0x32127190385ce4cf
+        .quad   0xa25cffc2dd6dea45
+        .quad   0x06409010bea8de75
+        .quad   0xd67cded679d34aa0
+        .quad   0xcc0b9ec0cc4db39f
+        .quad   0xa535a456e35d190f
+        .quad   0x2e05d9eaf61f6fef
+        .quad   0xc447901ad61beb59
+        .quad   0x661f19bce5dc880a
+        .quad   0x24685482b7ca6827
+        .quad   0x293c778cefe07f26
+
+        // 2^132 * 2 * B
+
+        .quad   0x86809e7007069096
+        .quad   0xaad75b15e4e50189
+        .quad   0x07f35715a21a0147
+        .quad   0x0487f3f112815d5e
+        .quad   0x16c795d6a11ff200
+        .quad   0xcb70d0e2b15815c9
+        .quad   0x89f293209b5395b5
+        .quad   0x50b8c2d031e47b4f
+        .quad   0x48350c08068a4962
+        .quad   0x6ffdd05351092c9a
+        .quad   0x17af4f4aaf6fc8dd
+        .quad   0x4b0553b53cdba58b
+
+        // 2^132 * 3 * B
+
+        .quad   0x9c65fcbe1b32ff79
+        .quad   0xeb75ea9f03b50f9b
+        .quad   0xfced2a6c6c07e606
+        .quad   0x35106cd551717908
+        .quad   0xbf05211b27c152d4
+        .quad   0x5ec26849bd1af639
+        .quad   0x5e0b2caa8e6fab98
+        .quad   0x054c8bdd50bd0840
+        .quad   0x38a0b12f1dcf073d
+        .quad   0x4b60a8a3b7f6a276
+        .quad   0xfed5ac25d3404f9a
+        .quad   0x72e82d5e5505c229
+
+        // 2^132 * 4 * B
+
+        .quad   0x6b0b697ff0d844c8
+        .quad   0xbb12f85cd979cb49
+        .quad   0xd2a541c6c1da0f1f
+        .quad   0x7b7c242958ce7211
+        .quad   0x00d9cdfd69771d02
+        .quad   0x410276cd6cfbf17e
+        .quad   0x4c45306c1cb12ec7
+        .quad   0x2857bf1627500861
+        .quad   0x9f21903f0101689e
+        .quad   0xd779dfd3bf861005
+        .quad   0xa122ee5f3deb0f1b
+        .quad   0x510df84b485a00d4
+
+        // 2^132 * 5 * B
+
+        .quad   0xa54133bb9277a1fa
+        .quad   0x74ec3b6263991237
+        .quad   0x1a3c54dc35d2f15a
+        .quad   0x2d347144e482ba3a
+        .quad   0x24b3c887c70ac15e
+        .quad   0xb0f3a557fb81b732
+        .quad   0x9b2cde2fe578cc1b
+        .quad   0x4cf7ed0703b54f8e
+        .quad   0x6bd47c6598fbee0f
+        .quad   0x9e4733e2ab55be2d
+        .quad   0x1093f624127610c5
+        .quad   0x4e05e26ad0a1eaa4
+
+        // 2^132 * 6 * B
+
+        .quad   0xda9b6b624b531f20
+        .quad   0x429a760e77509abb
+        .quad   0xdbe9f522e823cb80
+        .quad   0x618f1856880c8f82
+        .quad   0x1833c773e18fe6c0
+        .quad   0xe3c4711ad3c87265
+        .quad   0x3bfd3c4f0116b283
+        .quad   0x1955875eb4cd4db8
+        .quad   0x6da6de8f0e399799
+        .quad   0x7ad61aa440fda178
+        .quad   0xb32cd8105e3563dd
+        .quad   0x15f6beae2ae340ae
+
+        // 2^132 * 7 * B
+
+        .quad   0x862bcb0c31ec3a62
+        .quad   0x810e2b451138f3c2
+        .quad   0x788ec4b839dac2a4
+        .quad   0x28f76867ae2a9281
+        .quad   0xba9a0f7b9245e215
+        .quad   0xf368612dd98c0dbb
+        .quad   0x2e84e4cbf220b020
+        .quad   0x6ba92fe962d90eda
+        .quad   0x3e4df9655884e2aa
+        .quad   0xbd62fbdbdbd465a5
+        .quad   0xd7596caa0de9e524
+        .quad   0x6e8042ccb2b1b3d7
+
+        // 2^132 * 8 * B
+
+        .quad   0xf10d3c29ce28ca6e
+        .quad   0xbad34540fcb6093d
+        .quad   0xe7426ed7a2ea2d3f
+        .quad   0x08af9d4e4ff298b9
+        .quad   0x1530653616521f7e
+        .quad   0x660d06b896203dba
+        .quad   0x2d3989bc545f0879
+        .quad   0x4b5303af78ebd7b0
+        .quad   0x72f8a6c3bebcbde8
+        .quad   0x4f0fca4adc3a8e89
+        .quad   0x6fa9d4e8c7bfdf7a
+        .quad   0x0dcf2d679b624eb7
+
+        // 2^136 * 1 * B
+
+        .quad   0x3d5947499718289c
+        .quad   0x12ebf8c524533f26
+        .quad   0x0262bfcb14c3ef15
+        .quad   0x20b878d577b7518e
+        .quad   0x753941be5a45f06e
+        .quad   0xd07caeed6d9c5f65
+        .quad   0x11776b9c72ff51b6
+        .quad   0x17d2d1d9ef0d4da9
+        .quad   0x27f2af18073f3e6a
+        .quad   0xfd3fe519d7521069
+        .quad   0x22e3b72c3ca60022
+        .quad   0x72214f63cc65c6a7
+
+        // 2^136 * 2 * B
+
+        .quad   0xb4e37f405307a693
+        .quad   0xaba714d72f336795
+        .quad   0xd6fbd0a773761099
+        .quad   0x5fdf48c58171cbc9
+        .quad   0x1d9db7b9f43b29c9
+        .quad   0xd605824a4f518f75
+        .quad   0xf2c072bd312f9dc4
+        .quad   0x1f24ac855a1545b0
+        .quad   0x24d608328e9505aa
+        .quad   0x4748c1d10c1420ee
+        .quad   0xc7ffe45c06fb25a2
+        .quad   0x00ba739e2ae395e6
+
+        // 2^136 * 3 * B
+
+        .quad   0x592e98de5c8790d6
+        .quad   0xe5bfb7d345c2a2df
+        .quad   0x115a3b60f9b49922
+        .quad   0x03283a3e67ad78f3
+        .quad   0xae4426f5ea88bb26
+        .quad   0x360679d984973bfb
+        .quad   0x5c9f030c26694e50
+        .quad   0x72297de7d518d226
+        .quad   0x48241dc7be0cb939
+        .quad   0x32f19b4d8b633080
+        .quad   0xd3dfc90d02289308
+        .quad   0x05e1296846271945
+
+        // 2^136 * 4 * B
+
+        .quad   0xba82eeb32d9c495a
+        .quad   0xceefc8fcf12bb97c
+        .quad   0xb02dabae93b5d1e0
+        .quad   0x39c00c9c13698d9b
+        .quad   0xadbfbbc8242c4550
+        .quad   0xbcc80cecd03081d9
+        .quad   0x843566a6f5c8df92
+        .quad   0x78cf25d38258ce4c
+        .quad   0x15ae6b8e31489d68
+        .quad   0xaa851cab9c2bf087
+        .quad   0xc9a75a97f04efa05
+        .quad   0x006b52076b3ff832
+
+        // 2^136 * 5 * B
+
+        .quad   0x29e0cfe19d95781c
+        .quad   0xb681df18966310e2
+        .quad   0x57df39d370516b39
+        .quad   0x4d57e3443bc76122
+        .quad   0xf5cb7e16b9ce082d
+        .quad   0x3407f14c417abc29
+        .quad   0xd4b36bce2bf4a7ab
+        .quad   0x7de2e9561a9f75ce
+        .quad   0xde70d4f4b6a55ecb
+        .quad   0x4801527f5d85db99
+        .quad   0xdbc9c440d3ee9a81
+        .quad   0x6b2a90af1a6029ed
+
+        // 2^136 * 6 * B
+
+        .quad   0x6923f4fc9ae61e97
+        .quad   0x5735281de03f5fd1
+        .quad   0xa764ae43e6edd12d
+        .quad   0x5fd8f4e9d12d3e4a
+        .quad   0x77ebf3245bb2d80a
+        .quad   0xd8301b472fb9079b
+        .quad   0xc647e6f24cee7333
+        .quad   0x465812c8276c2109
+        .quad   0x4d43beb22a1062d9
+        .quad   0x7065fb753831dc16
+        .quad   0x180d4a7bde2968d7
+        .quad   0x05b32c2b1cb16790
+
+        // 2^136 * 7 * B
+
+        .quad   0xc8c05eccd24da8fd
+        .quad   0xa1cf1aac05dfef83
+        .quad   0xdbbeeff27df9cd61
+        .quad   0x3b5556a37b471e99
+        .quad   0xf7fca42c7ad58195
+        .quad   0x3214286e4333f3cc
+        .quad   0xb6c29d0d340b979d
+        .quad   0x31771a48567307e1
+        .quad   0x32b0c524e14dd482
+        .quad   0xedb351541a2ba4b6
+        .quad   0xa3d16048282b5af3
+        .quad   0x4fc079d27a7336eb
+
+        // 2^136 * 8 * B
+
+        .quad   0x51c938b089bf2f7f
+        .quad   0x2497bd6502dfe9a7
+        .quad   0xffffc09c7880e453
+        .quad   0x124567cecaf98e92
+        .quad   0xdc348b440c86c50d
+        .quad   0x1337cbc9cc94e651
+        .quad   0x6422f74d643e3cb9
+        .quad   0x241170c2bae3cd08
+        .quad   0x3ff9ab860ac473b4
+        .quad   0xf0911dee0113e435
+        .quad   0x4ae75060ebc6c4af
+        .quad   0x3f8612966c87000d
+
+        // 2^140 * 1 * B
+
+        .quad   0x0c9c5303f7957be4
+        .quad   0xa3c31a20e085c145
+        .quad   0xb0721d71d0850050
+        .quad   0x0aba390eab0bf2da
+        .quad   0x529fdffe638c7bf3
+        .quad   0xdf2b9e60388b4995
+        .quad   0xe027b34f1bad0249
+        .quad   0x7bc92fc9b9fa74ed
+        .quad   0x9f97ef2e801ad9f9
+        .quad   0x83697d5479afda3a
+        .quad   0xe906b3ffbd596b50
+        .quad   0x02672b37dd3fb8e0
+
+        // 2^140 * 2 * B
+
+        .quad   0x48b2ca8b260885e4
+        .quad   0xa4286bec82b34c1c
+        .quad   0x937e1a2617f58f74
+        .quad   0x741d1fcbab2ca2a5
+        .quad   0xee9ba729398ca7f5
+        .quad   0xeb9ca6257a4849db
+        .quad   0x29eb29ce7ec544e1
+        .quad   0x232ca21ef736e2c8
+        .quad   0xbf61423d253fcb17
+        .quad   0x08803ceafa39eb14
+        .quad   0xf18602df9851c7af
+        .quad   0x0400f3a049e3414b
+
+        // 2^140 * 3 * B
+
+        .quad   0xabce0476ba61c55b
+        .quad   0x36a3d6d7c4d39716
+        .quad   0x6eb259d5e8d82d09
+        .quad   0x0c9176e984d756fb
+        .quad   0x2efba412a06e7b06
+        .quad   0x146785452c8d2560
+        .quad   0xdf9713ebd67a91c7
+        .quad   0x32830ac7157eadf3
+        .quad   0x0e782a7ab73769e8
+        .quad   0x04a05d7875b18e2c
+        .quad   0x29525226ebcceae1
+        .quad   0x0d794f8383eba820
+
+        // 2^140 * 4 * B
+
+        .quad   0xff35f5cb9e1516f4
+        .quad   0xee805bcf648aae45
+        .quad   0xf0d73c2bb93a9ef3
+        .quad   0x097b0bf22092a6c2
+        .quad   0x7be44ce7a7a2e1ac
+        .quad   0x411fd93efad1b8b7
+        .quad   0x1734a1d70d5f7c9b
+        .quad   0x0d6592233127db16
+        .quad   0xc48bab1521a9d733
+        .quad   0xa6c2eaead61abb25
+        .quad   0x625c6c1cc6cb4305
+        .quad   0x7fc90fea93eb3a67
+
+        // 2^140 * 5 * B
+
+        .quad   0x0408f1fe1f5c5926
+        .quad   0x1a8f2f5e3b258bf4
+        .quad   0x40a951a2fdc71669
+        .quad   0x6598ee93c98b577e
+        .quad   0xc527deb59c7cb23d
+        .quad   0x955391695328404e
+        .quad   0xd64392817ccf2c7a
+        .quad   0x6ce97dabf7d8fa11
+        .quad   0x25b5a8e50ef7c48f
+        .quad   0xeb6034116f2ce532
+        .quad   0xc5e75173e53de537
+        .quad   0x73119fa08c12bb03
+
+        // 2^140 * 6 * B
+
+        .quad   0xed30129453f1a4cb
+        .quad   0xbce621c9c8f53787
+        .quad   0xfacb2b1338bee7b9
+        .quad   0x3025798a9ea8428c
+        .quad   0x7845b94d21f4774d
+        .quad   0xbf62f16c7897b727
+        .quad   0x671857c03c56522b
+        .quad   0x3cd6a85295621212
+        .quad   0x3fecde923aeca999
+        .quad   0xbdaa5b0062e8c12f
+        .quad   0x67b99dfc96988ade
+        .quad   0x3f52c02852661036
+
+        // 2^140 * 7 * B
+
+        .quad   0xffeaa48e2a1351c6
+        .quad   0x28624754fa7f53d7
+        .quad   0x0b5ba9e57582ddf1
+        .quad   0x60c0104ba696ac59
+        .quad   0x9258bf99eec416c6
+        .quad   0xac8a5017a9d2f671
+        .quad   0x629549ab16dea4ab
+        .quad   0x05d0e85c99091569
+        .quad   0x051de020de9cbe97
+        .quad   0xfa07fc56b50bcf74
+        .quad   0x378cec9f0f11df65
+        .quad   0x36853c69ab96de4d
+
+        // 2^140 * 8 * B
+
+        .quad   0x36d9b8de78f39b2d
+        .quad   0x7f42ed71a847b9ec
+        .quad   0x241cd1d679bd3fde
+        .quad   0x6a704fec92fbce6b
+        .quad   0x4433c0b0fac5e7be
+        .quad   0x724bae854c08dcbe
+        .quad   0xf1f24cc446978f9b
+        .quad   0x4a0aff6d62825fc8
+        .quad   0xe917fb9e61095301
+        .quad   0xc102df9402a092f8
+        .quad   0xbf09e2f5fa66190b
+        .quad   0x681109bee0dcfe37
+
+        // 2^144 * 1 * B
+
+        .quad   0x559a0cc9782a0dde
+        .quad   0x551dcdb2ea718385
+        .quad   0x7f62865b31ef238c
+        .quad   0x504aa7767973613d
+        .quad   0x9c18fcfa36048d13
+        .quad   0x29159db373899ddd
+        .quad   0xdc9f350b9f92d0aa
+        .quad   0x26f57eee878a19d4
+        .quad   0x0cab2cd55687efb1
+        .quad   0x5180d162247af17b
+        .quad   0x85c15a344f5a2467
+        .quad   0x4041943d9dba3069
+
+        // 2^144 * 2 * B
+
+        .quad   0xc3c0eeba43ebcc96
+        .quad   0x8d749c9c26ea9caf
+        .quad   0xd9fa95ee1c77ccc6
+        .quad   0x1420a1d97684340f
+        .quad   0x4b217743a26caadd
+        .quad   0x47a6b424648ab7ce
+        .quad   0xcb1d4f7a03fbc9e3
+        .quad   0x12d931429800d019
+        .quad   0x00c67799d337594f
+        .quad   0x5e3c5140b23aa47b
+        .quad   0x44182854e35ff395
+        .quad   0x1b4f92314359a012
+
+        // 2^144 * 3 * B
+
+        .quad   0x3e5c109d89150951
+        .quad   0x39cefa912de9696a
+        .quad   0x20eae43f975f3020
+        .quad   0x239b572a7f132dae
+        .quad   0x33cf3030a49866b1
+        .quad   0x251f73d2215f4859
+        .quad   0xab82aa4051def4f6
+        .quad   0x5ff191d56f9a23f6
+        .quad   0x819ed433ac2d9068
+        .quad   0x2883ab795fc98523
+        .quad   0xef4572805593eb3d
+        .quad   0x020c526a758f36cb
+
+        // 2^144 * 4 * B
+
+        .quad   0x779834f89ed8dbbc
+        .quad   0xc8f2aaf9dc7ca46c
+        .quad   0xa9524cdca3e1b074
+        .quad   0x02aacc4615313877
+        .quad   0xe931ef59f042cc89
+        .quad   0x2c589c9d8e124bb6
+        .quad   0xadc8e18aaec75997
+        .quad   0x452cfe0a5602c50c
+        .quad   0x86a0f7a0647877df
+        .quad   0xbbc464270e607c9f
+        .quad   0xab17ea25f1fb11c9
+        .quad   0x4cfb7d7b304b877b
+
+        // 2^144 * 5 * B
+
+        .quad   0x72b43d6cb89b75fe
+        .quad   0x54c694d99c6adc80
+        .quad   0xb8c3aa373ee34c9f
+        .quad   0x14b4622b39075364
+        .quad   0xe28699c29789ef12
+        .quad   0x2b6ecd71df57190d
+        .quad   0xc343c857ecc970d0
+        .quad   0x5b1d4cbc434d3ac5
+        .quad   0xb6fb2615cc0a9f26
+        .quad   0x3a4f0e2bb88dcce5
+        .quad   0x1301498b3369a705
+        .quad   0x2f98f71258592dd1
+
+        // 2^144 * 6 * B
+
+        .quad   0x0c94a74cb50f9e56
+        .quad   0x5b1ff4a98e8e1320
+        .quad   0x9a2acc2182300f67
+        .quad   0x3a6ae249d806aaf9
+        .quad   0x2e12ae444f54a701
+        .quad   0xfcfe3ef0a9cbd7de
+        .quad   0xcebf890d75835de0
+        .quad   0x1d8062e9e7614554
+        .quad   0x657ada85a9907c5a
+        .quad   0x1a0ea8b591b90f62
+        .quad   0x8d0e1dfbdf34b4e9
+        .quad   0x298b8ce8aef25ff3
+
+        // 2^144 * 7 * B
+
+        .quad   0x2a927953eff70cb2
+        .quad   0x4b89c92a79157076
+        .quad   0x9418457a30a7cf6a
+        .quad   0x34b8a8404d5ce485
+        .quad   0x837a72ea0a2165de
+        .quad   0x3fab07b40bcf79f6
+        .quad   0x521636c77738ae70
+        .quad   0x6ba6271803a7d7dc
+        .quad   0xc26eecb583693335
+        .quad   0xd5a813df63b5fefd
+        .quad   0xa293aa9aa4b22573
+        .quad   0x71d62bdd465e1c6a
+
+        // 2^144 * 8 * B
+
+        .quad   0x6533cc28d378df80
+        .quad   0xf6db43790a0fa4b4
+        .quad   0xe3645ff9f701da5a
+        .quad   0x74d5f317f3172ba4
+        .quad   0xcd2db5dab1f75ef5
+        .quad   0xd77f95cf16b065f5
+        .quad   0x14571fea3f49f085
+        .quad   0x1c333621262b2b3d
+        .quad   0xa86fe55467d9ca81
+        .quad   0x398b7c752b298c37
+        .quad   0xda6d0892e3ac623b
+        .quad   0x4aebcc4547e9d98c
+
+        // 2^148 * 1 * B
+
+        .quad   0x53175a7205d21a77
+        .quad   0xb0c04422d3b934d4
+        .quad   0xadd9f24bdd5deadc
+        .quad   0x074f46e69f10ff8c
+        .quad   0x0de9b204a059a445
+        .quad   0xe15cb4aa4b17ad0f
+        .quad   0xe1bbec521f79c557
+        .quad   0x2633f1b9d071081b
+        .quad   0xc1fb4177018b9910
+        .quad   0xa6ea20dc6c0fe140
+        .quad   0xd661f3e74354c6ff
+        .quad   0x5ecb72e6f1a3407a
+
+        // 2^148 * 2 * B
+
+        .quad   0xa515a31b2259fb4e
+        .quad   0x0960f3972bcac52f
+        .quad   0xedb52fec8d3454cb
+        .quad   0x382e2720c476c019
+        .quad   0xfeeae106e8e86997
+        .quad   0x9863337f98d09383
+        .quad   0x9470480eaa06ebef
+        .quad   0x038b6898d4c5c2d0
+        .quad   0xf391c51d8ace50a6
+        .quad   0x3142d0b9ae2d2948
+        .quad   0xdb4d5a1a7f24ca80
+        .quad   0x21aeba8b59250ea8
+
+        // 2^148 * 3 * B
+
+        .quad   0x24f13b34cf405530
+        .quad   0x3c44ea4a43088af7
+        .quad   0x5dd5c5170006a482
+        .quad   0x118eb8f8890b086d
+        .quad   0x53853600f0087f23
+        .quad   0x4c461879da7d5784
+        .quad   0x6af303deb41f6860
+        .quad   0x0a3c16c5c27c18ed
+        .quad   0x17e49c17cc947f3d
+        .quad   0xccc6eda6aac1d27b
+        .quad   0xdf6092ceb0f08e56
+        .quad   0x4909b3e22c67c36b
+
+        // 2^148 * 4 * B
+
+        .quad   0x9c9c85ea63fe2e89
+        .quad   0xbe1baf910e9412ec
+        .quad   0x8f7baa8a86fbfe7b
+        .quad   0x0fb17f9fef968b6c
+        .quad   0x59a16676706ff64e
+        .quad   0x10b953dd0d86a53d
+        .quad   0x5848e1e6ce5c0b96
+        .quad   0x2d8b78e712780c68
+        .quad   0x79d5c62eafc3902b
+        .quad   0x773a215289e80728
+        .quad   0xc38ae640e10120b9
+        .quad   0x09ae23717b2b1a6d
+
+        // 2^148 * 5 * B
+
+        .quad   0xbb6a192a4e4d083c
+        .quad   0x34ace0630029e192
+        .quad   0x98245a59aafabaeb
+        .quad   0x6d9c8a9ada97faac
+        .quad   0x10ab8fa1ad32b1d0
+        .quad   0xe9aced1be2778b24
+        .quad   0xa8856bc0373de90f
+        .quad   0x66f35ddddda53996
+        .quad   0xd27d9afb24997323
+        .quad   0x1bb7e07ef6f01d2e
+        .quad   0x2ba7472df52ecc7f
+        .quad   0x03019b4f646f9dc8
+
+        // 2^148 * 6 * B
+
+        .quad   0x04a186b5565345cd
+        .quad   0xeee76610bcc4116a
+        .quad   0x689c73b478fb2a45
+        .quad   0x387dcbff65697512
+        .quad   0xaf09b214e6b3dc6b
+        .quad   0x3f7573b5ad7d2f65
+        .quad   0xd019d988100a23b0
+        .quad   0x392b63a58b5c35f7
+        .quad   0x4093addc9c07c205
+        .quad   0xc565be15f532c37e
+        .quad   0x63dbecfd1583402a
+        .quad   0x61722b4aef2e032e
+
+        // 2^148 * 7 * B
+
+        .quad   0x0012aafeecbd47af
+        .quad   0x55a266fb1cd46309
+        .quad   0xf203eb680967c72c
+        .quad   0x39633944ca3c1429
+        .quad   0xd6b07a5581cb0e3c
+        .quad   0x290ff006d9444969
+        .quad   0x08680b6a16dcda1f
+        .quad   0x5568d2b75a06de59
+        .quad   0x8d0cb88c1b37cfe1
+        .quad   0x05b6a5a3053818f3
+        .quad   0xf2e9bc04b787d959
+        .quad   0x6beba1249add7f64
+
+        // 2^148 * 8 * B
+
+        .quad   0x1d06005ca5b1b143
+        .quad   0x6d4c6bb87fd1cda2
+        .quad   0x6ef5967653fcffe7
+        .quad   0x097c29e8c1ce1ea5
+        .quad   0x5c3cecb943f5a53b
+        .quad   0x9cc9a61d06c08df2
+        .quad   0xcfba639a85895447
+        .quad   0x5a845ae80df09fd5
+        .quad   0x4ce97dbe5deb94ca
+        .quad   0x38d0a4388c709c48
+        .quad   0xc43eced4a169d097
+        .quad   0x0a1249fff7e587c3
+
+        // 2^152 * 1 * B
+
+        .quad   0x12f0071b276d01c9
+        .quad   0xe7b8bac586c48c70
+        .quad   0x5308129b71d6fba9
+        .quad   0x5d88fbf95a3db792
+        .quad   0x0b408d9e7354b610
+        .quad   0x806b32535ba85b6e
+        .quad   0xdbe63a034a58a207
+        .quad   0x173bd9ddc9a1df2c
+        .quad   0x2b500f1efe5872df
+        .quad   0x58d6582ed43918c1
+        .quad   0xe6ed278ec9673ae0
+        .quad   0x06e1cd13b19ea319
+
+        // 2^152 * 2 * B
+
+        .quad   0x40d0ad516f166f23
+        .quad   0x118e32931fab6abe
+        .quad   0x3fe35e14a04d088e
+        .quad   0x3080603526e16266
+        .quad   0x472baf629e5b0353
+        .quad   0x3baa0b90278d0447
+        .quad   0x0c785f469643bf27
+        .quad   0x7f3a6a1a8d837b13
+        .quad   0xf7e644395d3d800b
+        .quad   0x95a8d555c901edf6
+        .quad   0x68cd7830592c6339
+        .quad   0x30d0fded2e51307e
+
+        // 2^152 * 3 * B
+
+        .quad   0xe0594d1af21233b3
+        .quad   0x1bdbe78ef0cc4d9c
+        .quad   0x6965187f8f499a77
+        .quad   0x0a9214202c099868
+        .quad   0x9cb4971e68b84750
+        .quad   0xa09572296664bbcf
+        .quad   0x5c8de72672fa412b
+        .quad   0x4615084351c589d9
+        .quad   0xbc9019c0aeb9a02e
+        .quad   0x55c7110d16034cae
+        .quad   0x0e6df501659932ec
+        .quad   0x3bca0d2895ca5dfe
+
+        // 2^152 * 4 * B
+
+        .quad   0x40f031bc3c5d62a4
+        .quad   0x19fc8b3ecff07a60
+        .quad   0x98183da2130fb545
+        .quad   0x5631deddae8f13cd
+        .quad   0x9c688eb69ecc01bf
+        .quad   0xf0bc83ada644896f
+        .quad   0xca2d955f5f7a9fe2
+        .quad   0x4ea8b4038df28241
+        .quad   0x2aed460af1cad202
+        .quad   0x46305305a48cee83
+        .quad   0x9121774549f11a5f
+        .quad   0x24ce0930542ca463
+
+        // 2^152 * 5 * B
+
+        .quad   0x1fe890f5fd06c106
+        .quad   0xb5c468355d8810f2
+        .quad   0x827808fe6e8caf3e
+        .quad   0x41d4e3c28a06d74b
+        .quad   0x3fcfa155fdf30b85
+        .quad   0xd2f7168e36372ea4
+        .quad   0xb2e064de6492f844
+        .quad   0x549928a7324f4280
+        .quad   0xf26e32a763ee1a2e
+        .quad   0xae91e4b7d25ffdea
+        .quad   0xbc3bd33bd17f4d69
+        .quad   0x491b66dec0dcff6a
+
+        // 2^152 * 6 * B
+
+        .quad   0x98f5b13dc7ea32a7
+        .quad   0xe3d5f8cc7e16db98
+        .quad   0xac0abf52cbf8d947
+        .quad   0x08f338d0c85ee4ac
+        .quad   0x75f04a8ed0da64a1
+        .quad   0xed222caf67e2284b
+        .quad   0x8234a3791f7b7ba4
+        .quad   0x4cf6b8b0b7018b67
+        .quad   0xc383a821991a73bd
+        .quad   0xab27bc01df320c7a
+        .quad   0xc13d331b84777063
+        .quad   0x530d4a82eb078a99
+
+        // 2^152 * 7 * B
+
+        .quad   0x004c3630e1f94825
+        .quad   0x7e2d78268cab535a
+        .quad   0xc7482323cc84ff8b
+        .quad   0x65ea753f101770b9
+        .quad   0x6d6973456c9abf9e
+        .quad   0x257fb2fc4900a880
+        .quad   0x2bacf412c8cfb850
+        .quad   0x0db3e7e00cbfbd5b
+        .quad   0x3d66fc3ee2096363
+        .quad   0x81d62c7f61b5cb6b
+        .quad   0x0fbe044213443b1a
+        .quad   0x02a4ec1921e1a1db
+
+        // 2^152 * 8 * B
+
+        .quad   0x5ce6259a3b24b8a2
+        .quad   0xb8577acc45afa0b8
+        .quad   0xcccbe6e88ba07037
+        .quad   0x3d143c51127809bf
+        .quad   0xf5c86162f1cf795f
+        .quad   0x118c861926ee57f2
+        .quad   0x172124851c063578
+        .quad   0x36d12b5dec067fcf
+        .quad   0x126d279179154557
+        .quad   0xd5e48f5cfc783a0a
+        .quad   0x36bdb6e8df179bac
+        .quad   0x2ef517885ba82859
+
+        // 2^156 * 1 * B
+
+        .quad   0x88bd438cd11e0d4a
+        .quad   0x30cb610d43ccf308
+        .quad   0xe09a0e3791937bcc
+        .quad   0x4559135b25b1720c
+        .quad   0x1ea436837c6da1e9
+        .quad   0xf9c189af1fb9bdbe
+        .quad   0x303001fcce5dd155
+        .quad   0x28a7c99ebc57be52
+        .quad   0xb8fd9399e8d19e9d
+        .quad   0x908191cb962423ff
+        .quad   0xb2b948d747c742a3
+        .quad   0x37f33226d7fb44c4
+
+        // 2^156 * 2 * B
+
+        .quad   0x0dae8767b55f6e08
+        .quad   0x4a43b3b35b203a02
+        .quad   0xe3725a6e80af8c79
+        .quad   0x0f7a7fd1705fa7a3
+        .quad   0x33912553c821b11d
+        .quad   0x66ed42c241e301df
+        .quad   0x066fcc11104222fd
+        .quad   0x307a3b41c192168f
+        .quad   0x8eeb5d076eb55ce0
+        .quad   0x2fc536bfaa0d925a
+        .quad   0xbe81830fdcb6c6e8
+        .quad   0x556c7045827baf52
+
+        // 2^156 * 3 * B
+
+        .quad   0x8e2b517302e9d8b7
+        .quad   0xe3e52269248714e8
+        .quad   0xbd4fbd774ca960b5
+        .quad   0x6f4b4199c5ecada9
+        .quad   0xb94b90022bf44406
+        .quad   0xabd4237eff90b534
+        .quad   0x7600a960faf86d3a
+        .quad   0x2f45abdac2322ee3
+        .quad   0x61af4912c8ef8a6a
+        .quad   0xe58fa4fe43fb6e5e
+        .quad   0xb5afcc5d6fd427cf
+        .quad   0x6a5393281e1e11eb
+
+        // 2^156 * 4 * B
+
+        .quad   0xf3da5139a5d1ee89
+        .quad   0x8145457cff936988
+        .quad   0x3f622fed00e188c4
+        .quad   0x0f513815db8b5a3d
+        .quad   0x0fff04fe149443cf
+        .quad   0x53cac6d9865cddd7
+        .quad   0x31385b03531ed1b7
+        .quad   0x5846a27cacd1039d
+        .quad   0x4ff5cdac1eb08717
+        .quad   0x67e8b29590f2e9bc
+        .quad   0x44093b5e237afa99
+        .quad   0x0d414bed8708b8b2
+
+        // 2^156 * 5 * B
+
+        .quad   0xcfb68265fd0e75f6
+        .quad   0xe45b3e28bb90e707
+        .quad   0x7242a8de9ff92c7a
+        .quad   0x685b3201933202dd
+        .quad   0x81886a92294ac9e8
+        .quad   0x23162b45d55547be
+        .quad   0x94cfbc4403715983
+        .quad   0x50eb8fdb134bc401
+        .quad   0xc0b73ec6d6b330cd
+        .quad   0x84e44807132faff1
+        .quad   0x732b7352c4a5dee1
+        .quad   0x5d7c7cf1aa7cd2d2
+
+        // 2^156 * 6 * B
+
+        .quad   0xaf3b46bf7a4aafa2
+        .quad   0xb78705ec4d40d411
+        .quad   0x114f0c6aca7c15e3
+        .quad   0x3f364faaa9489d4d
+        .quad   0x33d1013e9b73a562
+        .quad   0x925cef5748ec26e1
+        .quad   0xa7fce614dd468058
+        .quad   0x78b0fad41e9aa438
+        .quad   0xbf56a431ed05b488
+        .quad   0xa533e66c9c495c7e
+        .quad   0xe8652baf87f3651a
+        .quad   0x0241800059d66c33
+
+        // 2^156 * 7 * B
+
+        .quad   0xceb077fea37a5be4
+        .quad   0xdb642f02e5a5eeb7
+        .quad   0xc2e6d0c5471270b8
+        .quad   0x4771b65538e4529c
+        .quad   0x28350c7dcf38ea01
+        .quad   0x7c6cdbc0b2917ab6
+        .quad   0xace7cfbe857082f7
+        .quad   0x4d2845aba2d9a1e0
+        .quad   0xbb537fe0447070de
+        .quad   0xcba744436dd557df
+        .quad   0xd3b5a3473600dbcb
+        .quad   0x4aeabbe6f9ffd7f8
+
+        // 2^156 * 8 * B
+
+        .quad   0x4630119e40d8f78c
+        .quad   0xa01a9bc53c710e11
+        .quad   0x486d2b258910dd79
+        .quad   0x1e6c47b3db0324e5
+        .quad   0x6a2134bcc4a9c8f2
+        .quad   0xfbf8fd1c8ace2e37
+        .quad   0x000ae3049911a0ba
+        .quad   0x046e3a616bc89b9e
+        .quad   0x14e65442f03906be
+        .quad   0x4a019d54e362be2a
+        .quad   0x68ccdfec8dc230c7
+        .quad   0x7cfb7e3faf6b861c
+
+        // 2^160 * 1 * B
+
+        .quad   0x4637974e8c58aedc
+        .quad   0xb9ef22fbabf041a4
+        .quad   0xe185d956e980718a
+        .quad   0x2f1b78fab143a8a6
+        .quad   0x96eebffb305b2f51
+        .quad   0xd3f938ad889596b8
+        .quad   0xf0f52dc746d5dd25
+        .quad   0x57968290bb3a0095
+        .quad   0xf71ab8430a20e101
+        .quad   0xf393658d24f0ec47
+        .quad   0xcf7509a86ee2eed1
+        .quad   0x7dc43e35dc2aa3e1
+
+        // 2^160 * 2 * B
+
+        .quad   0x85966665887dd9c3
+        .quad   0xc90f9b314bb05355
+        .quad   0xc6e08df8ef2079b1
+        .quad   0x7ef72016758cc12f
+        .quad   0x5a782a5c273e9718
+        .quad   0x3576c6995e4efd94
+        .quad   0x0f2ed8051f237d3e
+        .quad   0x044fb81d82d50a99
+        .quad   0xc1df18c5a907e3d9
+        .quad   0x57b3371dce4c6359
+        .quad   0xca704534b201bb49
+        .quad   0x7f79823f9c30dd2e
+
+        // 2^160 * 3 * B
+
+        .quad   0x8334d239a3b513e8
+        .quad   0xc13670d4b91fa8d8
+        .quad   0x12b54136f590bd33
+        .quad   0x0a4e0373d784d9b4
+        .quad   0x6a9c1ff068f587ba
+        .quad   0x0827894e0050c8de
+        .quad   0x3cbf99557ded5be7
+        .quad   0x64a9b0431c06d6f0
+        .quad   0x2eb3d6a15b7d2919
+        .quad   0xb0b4f6a0d53a8235
+        .quad   0x7156ce4389a45d47
+        .quad   0x071a7d0ace18346c
+
+        // 2^160 * 4 * B
+
+        .quad   0xd3072daac887ba0b
+        .quad   0x01262905bfa562ee
+        .quad   0xcf543002c0ef768b
+        .quad   0x2c3bcc7146ea7e9c
+        .quad   0xcc0c355220e14431
+        .quad   0x0d65950709b15141
+        .quad   0x9af5621b209d5f36
+        .quad   0x7c69bcf7617755d3
+        .quad   0x07f0d7eb04e8295f
+        .quad   0x10db18252f50f37d
+        .quad   0xe951a9a3171798d7
+        .quad   0x6f5a9a7322aca51d
+
+        // 2^160 * 5 * B
+
+        .quad   0x8ba1000c2f41c6c5
+        .quad   0xc49f79c10cfefb9b
+        .quad   0x4efa47703cc51c9f
+        .quad   0x494e21a2e147afca
+        .quad   0xe729d4eba3d944be
+        .quad   0x8d9e09408078af9e
+        .quad   0x4525567a47869c03
+        .quad   0x02ab9680ee8d3b24
+        .quad   0xefa48a85dde50d9a
+        .quad   0x219a224e0fb9a249
+        .quad   0xfa091f1dd91ef6d9
+        .quad   0x6b5d76cbea46bb34
+
+        // 2^160 * 6 * B
+
+        .quad   0x8857556cec0cd994
+        .quad   0x6472dc6f5cd01dba
+        .quad   0xaf0169148f42b477
+        .quad   0x0ae333f685277354
+        .quad   0xe0f941171e782522
+        .quad   0xf1e6ae74036936d3
+        .quad   0x408b3ea2d0fcc746
+        .quad   0x16fb869c03dd313e
+        .quad   0x288e199733b60962
+        .quad   0x24fc72b4d8abe133
+        .quad   0x4811f7ed0991d03e
+        .quad   0x3f81e38b8f70d075
+
+        // 2^160 * 7 * B
+
+        .quad   0x7f910fcc7ed9affe
+        .quad   0x545cb8a12465874b
+        .quad   0xa8397ed24b0c4704
+        .quad   0x50510fc104f50993
+        .quad   0x0adb7f355f17c824
+        .quad   0x74b923c3d74299a4
+        .quad   0xd57c3e8bcbf8eaf7
+        .quad   0x0ad3e2d34cdedc3d
+        .quad   0x6f0c0fc5336e249d
+        .quad   0x745ede19c331cfd9
+        .quad   0xf2d6fd0009eefe1c
+        .quad   0x127c158bf0fa1ebe
+
+        // 2^160 * 8 * B
+
+        .quad   0xf6197c422e9879a2
+        .quad   0xa44addd452ca3647
+        .quad   0x9b413fc14b4eaccb
+        .quad   0x354ef87d07ef4f68
+        .quad   0xdea28fc4ae51b974
+        .quad   0x1d9973d3744dfe96
+        .quad   0x6240680b873848a8
+        .quad   0x4ed82479d167df95
+        .quad   0xfee3b52260c5d975
+        .quad   0x50352efceb41b0b8
+        .quad   0x8808ac30a9f6653c
+        .quad   0x302d92d20539236d
+
+        // 2^164 * 1 * B
+
+        .quad   0x4c59023fcb3efb7c
+        .quad   0x6c2fcb99c63c2a94
+        .quad   0xba4190e2c3c7e084
+        .quad   0x0e545daea51874d9
+        .quad   0x957b8b8b0df53c30
+        .quad   0x2a1c770a8e60f098
+        .quad   0xbbc7a670345796de
+        .quad   0x22a48f9a90c99bc9
+        .quad   0x6b7dc0dc8d3fac58
+        .quad   0x5497cd6ce6e42bfd
+        .quad   0x542f7d1bf400d305
+        .quad   0x4159f47f048d9136
+
+        // 2^164 * 2 * B
+
+        .quad   0x20ad660839e31e32
+        .quad   0xf81e1bd58405be50
+        .quad   0xf8064056f4dabc69
+        .quad   0x14d23dd4ce71b975
+        .quad   0x748515a8bbd24839
+        .quad   0x77128347afb02b55
+        .quad   0x50ba2ac649a2a17f
+        .quad   0x060525513ad730f1
+        .quad   0xf2398e098aa27f82
+        .quad   0x6d7982bb89a1b024
+        .quad   0xfa694084214dd24c
+        .quad   0x71ab966fa32301c3
+
+        // 2^164 * 3 * B
+
+        .quad   0x2dcbd8e34ded02fc
+        .quad   0x1151f3ec596f22aa
+        .quad   0xbca255434e0328da
+        .quad   0x35768fbe92411b22
+        .quad   0xb1088a0702809955
+        .quad   0x43b273ea0b43c391
+        .quad   0xca9b67aefe0686ed
+        .quad   0x605eecbf8335f4ed
+        .quad   0x83200a656c340431
+        .quad   0x9fcd71678ee59c2f
+        .quad   0x75d4613f71300f8a
+        .quad   0x7a912faf60f542f9
+
+        // 2^164 * 4 * B
+
+        .quad   0xb204585e5edc1a43
+        .quad   0x9f0e16ee5897c73c
+        .quad   0x5b82c0ae4e70483c
+        .quad   0x624a170e2bddf9be
+        .quad   0x253f4f8dfa2d5597
+        .quad   0x25e49c405477130c
+        .quad   0x00c052e5996b1102
+        .quad   0x33cb966e33bb6c4a
+        .quad   0x597028047f116909
+        .quad   0x828ac41c1e564467
+        .quad   0x70417dbde6217387
+        .quad   0x721627aefbac4384
+
+        // 2^164 * 5 * B
+
+        .quad   0x97d03bc38736add5
+        .quad   0x2f1422afc532b130
+        .quad   0x3aa68a057101bbc4
+        .quad   0x4c946cf7e74f9fa7
+        .quad   0xfd3097bc410b2f22
+        .quad   0xf1a05da7b5cfa844
+        .quad   0x61289a1def57ca74
+        .quad   0x245ea199bb821902
+        .quad   0xaedca66978d477f8
+        .quad   0x1898ba3c29117fe1
+        .quad   0xcf73f983720cbd58
+        .quad   0x67da12e6b8b56351
+
+        // 2^164 * 6 * B
+
+        .quad   0x7067e187b4bd6e07
+        .quad   0x6e8f0203c7d1fe74
+        .quad   0x93c6aa2f38c85a30
+        .quad   0x76297d1f3d75a78a
+        .quad   0x2b7ef3d38ec8308c
+        .quad   0x828fd7ec71eb94ab
+        .quad   0x807c3b36c5062abd
+        .quad   0x0cb64cb831a94141
+        .quad   0x3030fc33534c6378
+        .quad   0xb9635c5ce541e861
+        .quad   0x15d9a9bed9b2c728
+        .quad   0x49233ea3f3775dcb
+
+        // 2^164 * 7 * B
+
+        .quad   0x629398fa8dbffc3a
+        .quad   0xe12fe52dd54db455
+        .quad   0xf3be11dfdaf25295
+        .quad   0x628b140dce5e7b51
+        .quad   0x7b3985fe1c9f249b
+        .quad   0x4fd6b2d5a1233293
+        .quad   0xceb345941adf4d62
+        .quad   0x6987ff6f542de50c
+        .quad   0x47e241428f83753c
+        .quad   0x6317bebc866af997
+        .quad   0xdabb5b433d1a9829
+        .quad   0x074d8d245287fb2d
+
+        // 2^164 * 8 * B
+
+        .quad   0x8337d9cd440bfc31
+        .quad   0x729d2ca1af318fd7
+        .quad   0xa040a4a4772c2070
+        .quad   0x46002ef03a7349be
+        .quad   0x481875c6c0e31488
+        .quad   0x219429b2e22034b4
+        .quad   0x7223c98a31283b65
+        .quad   0x3420d60b342277f9
+        .quad   0xfaa23adeaffe65f7
+        .quad   0x78261ed45be0764c
+        .quad   0x441c0a1e2f164403
+        .quad   0x5aea8e567a87d395
+
+        // 2^168 * 1 * B
+
+        .quad   0x7813c1a2bca4283d
+        .quad   0xed62f091a1863dd9
+        .quad   0xaec7bcb8c268fa86
+        .quad   0x10e5d3b76f1cae4c
+        .quad   0x2dbc6fb6e4e0f177
+        .quad   0x04e1bf29a4bd6a93
+        .quad   0x5e1966d4787af6e8
+        .quad   0x0edc5f5eb426d060
+        .quad   0x5453bfd653da8e67
+        .quad   0xe9dc1eec24a9f641
+        .quad   0xbf87263b03578a23
+        .quad   0x45b46c51361cba72
+
+        // 2^168 * 2 * B
+
+        .quad   0xa9402abf314f7fa1
+        .quad   0xe257f1dc8e8cf450
+        .quad   0x1dbbd54b23a8be84
+        .quad   0x2177bfa36dcb713b
+        .quad   0xce9d4ddd8a7fe3e4
+        .quad   0xab13645676620e30
+        .quad   0x4b594f7bb30e9958
+        .quad   0x5c1c0aef321229df
+        .quad   0x37081bbcfa79db8f
+        .quad   0x6048811ec25f59b3
+        .quad   0x087a76659c832487
+        .quad   0x4ae619387d8ab5bb
+
+        // 2^168 * 3 * B
+
+        .quad   0x8ddbf6aa5344a32e
+        .quad   0x7d88eab4b41b4078
+        .quad   0x5eb0eb974a130d60
+        .quad   0x1a00d91b17bf3e03
+        .quad   0x61117e44985bfb83
+        .quad   0xfce0462a71963136
+        .quad   0x83ac3448d425904b
+        .quad   0x75685abe5ba43d64
+        .quad   0x6e960933eb61f2b2
+        .quad   0x543d0fa8c9ff4952
+        .quad   0xdf7275107af66569
+        .quad   0x135529b623b0e6aa
+
+        // 2^168 * 4 * B
+
+        .quad   0x18f0dbd7add1d518
+        .quad   0x979f7888cfc11f11
+        .quad   0x8732e1f07114759b
+        .quad   0x79b5b81a65ca3a01
+        .quad   0xf5c716bce22e83fe
+        .quad   0xb42beb19e80985c1
+        .quad   0xec9da63714254aae
+        .quad   0x5972ea051590a613
+        .quad   0x0fd4ac20dc8f7811
+        .quad   0x9a9ad294ac4d4fa8
+        .quad   0xc01b2d64b3360434
+        .quad   0x4f7e9c95905f3bdb
+
+        // 2^168 * 5 * B
+
+        .quad   0x62674bbc5781302e
+        .quad   0xd8520f3989addc0f
+        .quad   0x8c2999ae53fbd9c6
+        .quad   0x31993ad92e638e4c
+        .quad   0x71c8443d355299fe
+        .quad   0x8bcd3b1cdbebead7
+        .quad   0x8092499ef1a49466
+        .quad   0x1942eec4a144adc8
+        .quad   0x7dac5319ae234992
+        .quad   0x2c1b3d910cea3e92
+        .quad   0x553ce494253c1122
+        .quad   0x2a0a65314ef9ca75
+
+        // 2^168 * 6 * B
+
+        .quad   0x2db7937ff7f927c2
+        .quad   0xdb741f0617d0a635
+        .quad   0x5982f3a21155af76
+        .quad   0x4cf6e218647c2ded
+        .quad   0xcf361acd3c1c793a
+        .quad   0x2f9ebcac5a35bc3b
+        .quad   0x60e860e9a8cda6ab
+        .quad   0x055dc39b6dea1a13
+        .quad   0xb119227cc28d5bb6
+        .quad   0x07e24ebc774dffab
+        .quad   0xa83c78cee4a32c89
+        .quad   0x121a307710aa24b6
+
+        // 2^168 * 7 * B
+
+        .quad   0xe4db5d5e9f034a97
+        .quad   0xe153fc093034bc2d
+        .quad   0x460546919551d3b1
+        .quad   0x333fc76c7a40e52d
+        .quad   0xd659713ec77483c9
+        .quad   0x88bfe077b82b96af
+        .quad   0x289e28231097bcd3
+        .quad   0x527bb94a6ced3a9b
+        .quad   0x563d992a995b482e
+        .quad   0x3405d07c6e383801
+        .quad   0x485035de2f64d8e5
+        .quad   0x6b89069b20a7a9f7
+
+        // 2^168 * 8 * B
+
+        .quad   0x812aa0416270220d
+        .quad   0x995a89faf9245b4e
+        .quad   0xffadc4ce5072ef05
+        .quad   0x23bc2103aa73eb73
+        .quad   0x4082fa8cb5c7db77
+        .quad   0x068686f8c734c155
+        .quad   0x29e6c8d9f6e7a57e
+        .quad   0x0473d308a7639bcf
+        .quad   0xcaee792603589e05
+        .quad   0x2b4b421246dcc492
+        .quad   0x02a1ef74e601a94f
+        .quad   0x102f73bfde04341a
+
+        // 2^172 * 1 * B
+
+        .quad   0xb5a2d50c7ec20d3e
+        .quad   0xc64bdd6ea0c97263
+        .quad   0x56e89052c1ff734d
+        .quad   0x4929c6f72b2ffaba
+        .quad   0x358ecba293a36247
+        .quad   0xaf8f9862b268fd65
+        .quad   0x412f7e9968a01c89
+        .quad   0x5786f312cd754524
+        .quad   0x337788ffca14032c
+        .quad   0xf3921028447f1ee3
+        .quad   0x8b14071f231bccad
+        .quad   0x4c817b4bf2344783
+
+        // 2^172 * 2 * B
+
+        .quad   0x0ff853852871b96e
+        .quad   0xe13e9fab60c3f1bb
+        .quad   0xeefd595325344402
+        .quad   0x0a37c37075b7744b
+        .quad   0x413ba057a40b4484
+        .quad   0xba4c2e1a4f5f6a43
+        .quad   0x614ba0a5aee1d61c
+        .quad   0x78a1531a8b05dc53
+        .quad   0x6cbdf1703ad0562b
+        .quad   0x8ecf4830c92521a3
+        .quad   0xdaebd303fd8424e7
+        .quad   0x72ad82a42e5ec56f
+
+        // 2^172 * 3 * B
+
+        .quad   0x3f9e8e35bafb65f6
+        .quad   0x39d69ec8f27293a1
+        .quad   0x6cb8cd958cf6a3d0
+        .quad   0x1734778173adae6d
+        .quad   0xc368939167024bc3
+        .quad   0x8e69d16d49502fda
+        .quad   0xfcf2ec3ce45f4b29
+        .quad   0x065f669ea3b4cbc4
+        .quad   0x8a00aec75532db4d
+        .quad   0xb869a4e443e31bb1
+        .quad   0x4a0f8552d3a7f515
+        .quad   0x19adeb7c303d7c08
+
+        // 2^172 * 4 * B
+
+        .quad   0xc720cb6153ead9a3
+        .quad   0x55b2c97f512b636e
+        .quad   0xb1e35b5fd40290b1
+        .quad   0x2fd9ccf13b530ee2
+        .quad   0x9d05ba7d43c31794
+        .quad   0x2470c8ff93322526
+        .quad   0x8323dec816197438
+        .quad   0x2852709881569b53
+        .quad   0x07bd475b47f796b8
+        .quad   0xd2c7b013542c8f54
+        .quad   0x2dbd23f43b24f87e
+        .quad   0x6551afd77b0901d6
+
+        // 2^172 * 5 * B
+
+        .quad   0x4546baaf54aac27f
+        .quad   0xf6f66fecb2a45a28
+        .quad   0x582d1b5b562bcfe8
+        .quad   0x44b123f3920f785f
+        .quad   0x68a24ce3a1d5c9ac
+        .quad   0xbb77a33d10ff6461
+        .quad   0x0f86ce4425d3166e
+        .quad   0x56507c0950b9623b
+        .quad   0x1206f0b7d1713e63
+        .quad   0x353fe3d915bafc74
+        .quad   0x194ceb970ad9d94d
+        .quad   0x62fadd7cf9d03ad3
+
+        // 2^172 * 6 * B
+
+        .quad   0xc6b5967b5598a074
+        .quad   0x5efe91ce8e493e25
+        .quad   0xd4b72c4549280888
+        .quad   0x20ef1149a26740c2
+        .quad   0x3cd7bc61e7ce4594
+        .quad   0xcd6b35a9b7dd267e
+        .quad   0xa080abc84366ef27
+        .quad   0x6ec7c46f59c79711
+        .quad   0x2f07ad636f09a8a2
+        .quad   0x8697e6ce24205e7d
+        .quad   0xc0aefc05ee35a139
+        .quad   0x15e80958b5f9d897
+
+        // 2^172 * 7 * B
+
+        .quad   0x25a5ef7d0c3e235b
+        .quad   0x6c39c17fbe134ee7
+        .quad   0xc774e1342dc5c327
+        .quad   0x021354b892021f39
+        .quad   0x4dd1ed355bb061c4
+        .quad   0x42dc0cef941c0700
+        .quad   0x61305dc1fd86340e
+        .quad   0x56b2cc930e55a443
+        .quad   0x1df79da6a6bfc5a2
+        .quad   0x02f3a2749fde4369
+        .quad   0xb323d9f2cda390a7
+        .quad   0x7be0847b8774d363
+
+        // 2^172 * 8 * B
+
+        .quad   0x8c99cc5a8b3f55c3
+        .quad   0x0611d7253fded2a0
+        .quad   0xed2995ff36b70a36
+        .quad   0x1f699a54d78a2619
+        .quad   0x1466f5af5307fa11
+        .quad   0x817fcc7ded6c0af2
+        .quad   0x0a6de44ec3a4a3fb
+        .quad   0x74071475bc927d0b
+        .quad   0xe77292f373e7ea8a
+        .quad   0x296537d2cb045a31
+        .quad   0x1bd0653ed3274fde
+        .quad   0x2f9a2c4476bd2966
+
+        // 2^176 * 1 * B
+
+        .quad   0xeb18b9ab7f5745c6
+        .quad   0x023a8aee5787c690
+        .quad   0xb72712da2df7afa9
+        .quad   0x36597d25ea5c013d
+        .quad   0xa2b4dae0b5511c9a
+        .quad   0x7ac860292bffff06
+        .quad   0x981f375df5504234
+        .quad   0x3f6bd725da4ea12d
+        .quad   0x734d8d7b106058ac
+        .quad   0xd940579e6fc6905f
+        .quad   0x6466f8f99202932d
+        .quad   0x7b7ecc19da60d6d0
+
+        // 2^176 * 2 * B
+
+        .quad   0x78c2373c695c690d
+        .quad   0xdd252e660642906e
+        .quad   0x951d44444ae12bd2
+        .quad   0x4235ad7601743956
+        .quad   0x6dae4a51a77cfa9b
+        .quad   0x82263654e7a38650
+        .quad   0x09bbffcd8f2d82db
+        .quad   0x03bedc661bf5caba
+        .quad   0x6258cb0d078975f5
+        .quad   0x492942549189f298
+        .quad   0xa0cab423e2e36ee4
+        .quad   0x0e7ce2b0cdf066a1
+
+        // 2^176 * 3 * B
+
+        .quad   0xc494643ac48c85a3
+        .quad   0xfd361df43c6139ad
+        .quad   0x09db17dd3ae94d48
+        .quad   0x666e0a5d8fb4674a
+        .quad   0xfea6fedfd94b70f9
+        .quad   0xf130c051c1fcba2d
+        .quad   0x4882d47e7f2fab89
+        .quad   0x615256138aeceeb5
+        .quad   0x2abbf64e4870cb0d
+        .quad   0xcd65bcf0aa458b6b
+        .quad   0x9abe4eba75e8985d
+        .quad   0x7f0bc810d514dee4
+
+        // 2^176 * 4 * B
+
+        .quad   0xb9006ba426f4136f
+        .quad   0x8d67369e57e03035
+        .quad   0xcbc8dfd94f463c28
+        .quad   0x0d1f8dbcf8eedbf5
+        .quad   0x83ac9dad737213a0
+        .quad   0x9ff6f8ba2ef72e98
+        .quad   0x311e2edd43ec6957
+        .quad   0x1d3a907ddec5ab75
+        .quad   0xba1693313ed081dc
+        .quad   0x29329fad851b3480
+        .quad   0x0128013c030321cb
+        .quad   0x00011b44a31bfde3
+
+        // 2^176 * 5 * B
+
+        .quad   0x3fdfa06c3fc66c0c
+        .quad   0x5d40e38e4dd60dd2
+        .quad   0x7ae38b38268e4d71
+        .quad   0x3ac48d916e8357e1
+        .quad   0x16561f696a0aa75c
+        .quad   0xc1bf725c5852bd6a
+        .quad   0x11a8dd7f9a7966ad
+        .quad   0x63d988a2d2851026
+        .quad   0x00120753afbd232e
+        .quad   0xe92bceb8fdd8f683
+        .quad   0xf81669b384e72b91
+        .quad   0x33fad52b2368a066
+
+        // 2^176 * 6 * B
+
+        .quad   0x540649c6c5e41e16
+        .quad   0x0af86430333f7735
+        .quad   0xb2acfcd2f305e746
+        .quad   0x16c0f429a256dca7
+        .quad   0x8d2cc8d0c422cfe8
+        .quad   0x072b4f7b05a13acb
+        .quad   0xa3feb6e6ecf6a56f
+        .quad   0x3cc355ccb90a71e2
+        .quad   0xe9b69443903e9131
+        .quad   0xb8a494cb7a5637ce
+        .quad   0xc87cd1a4baba9244
+        .quad   0x631eaf426bae7568
+
+        // 2^176 * 7 * B
+
+        .quad   0xb3e90410da66fe9f
+        .quad   0x85dd4b526c16e5a6
+        .quad   0xbc3d97611ef9bf83
+        .quad   0x5599648b1ea919b5
+        .quad   0x47d975b9a3700de8
+        .quad   0x7280c5fbe2f80552
+        .quad   0x53658f2732e45de1
+        .quad   0x431f2c7f665f80b5
+        .quad   0xd6026344858f7b19
+        .quad   0x14ab352fa1ea514a
+        .quad   0x8900441a2090a9d7
+        .quad   0x7b04715f91253b26
+
+        // 2^176 * 8 * B
+
+        .quad   0x83edbd28acf6ae43
+        .quad   0x86357c8b7d5c7ab4
+        .quad   0xc0404769b7eb2c44
+        .quad   0x59b37bf5c2f6583f
+        .quad   0xb376c280c4e6bac6
+        .quad   0x970ed3dd6d1d9b0b
+        .quad   0xb09a9558450bf944
+        .quad   0x48d0acfa57cde223
+        .quad   0xb60f26e47dabe671
+        .quad   0xf1d1a197622f3a37
+        .quad   0x4208ce7ee9960394
+        .quad   0x16234191336d3bdb
+
+        // 2^180 * 1 * B
+
+        .quad   0xf19aeac733a63aef
+        .quad   0x2c7fba5d4442454e
+        .quad   0x5da87aa04795e441
+        .quad   0x413051e1a4e0b0f5
+        .quad   0x852dd1fd3d578bbe
+        .quad   0x2b65ce72c3286108
+        .quad   0x658c07f4eace2273
+        .quad   0x0933f804ec38ab40
+        .quad   0xa7ab69798d496476
+        .quad   0x8121aadefcb5abc8
+        .quad   0xa5dc12ef7b539472
+        .quad   0x07fd47065e45351a
+
+        // 2^180 * 2 * B
+
+        .quad   0xc8583c3d258d2bcd
+        .quad   0x17029a4daf60b73f
+        .quad   0xfa0fc9d6416a3781
+        .quad   0x1c1e5fba38b3fb23
+        .quad   0x304211559ae8e7c3
+        .quad   0xf281b229944882a5
+        .quad   0x8a13ac2e378250e4
+        .quad   0x014afa0954ba48f4
+        .quad   0xcb3197001bb3666c
+        .quad   0x330060524bffecb9
+        .quad   0x293711991a88233c
+        .quad   0x291884363d4ed364
+
+        // 2^180 * 3 * B
+
+        .quad   0x033c6805dc4babfa
+        .quad   0x2c15bf5e5596ecc1
+        .quad   0x1bc70624b59b1d3b
+        .quad   0x3ede9850a19f0ec5
+        .quad   0xfb9d37c3bc1ab6eb
+        .quad   0x02be14534d57a240
+        .quad   0xf4d73415f8a5e1f6
+        .quad   0x5964f4300ccc8188
+        .quad   0xe44a23152d096800
+        .quad   0x5c08c55970866996
+        .quad   0xdf2db60a46affb6e
+        .quad   0x579155c1f856fd89
+
+        // 2^180 * 4 * B
+
+        .quad   0x96324edd12e0c9ef
+        .quad   0x468b878df2420297
+        .quad   0x199a3776a4f573be
+        .quad   0x1e7fbcf18e91e92a
+        .quad   0xb5f16b630817e7a6
+        .quad   0x808c69233c351026
+        .quad   0x324a983b54cef201
+        .quad   0x53c092084a485345
+        .quad   0xd2d41481f1cbafbf
+        .quad   0x231d2db6716174e5
+        .quad   0x0b7d7656e2a55c98
+        .quad   0x3e955cd82aa495f6
+
+        // 2^180 * 5 * B
+
+        .quad   0xe48f535e3ed15433
+        .quad   0xd075692a0d7270a3
+        .quad   0x40fbd21daade6387
+        .quad   0x14264887cf4495f5
+        .quad   0xab39f3ef61bb3a3f
+        .quad   0x8eb400652eb9193e
+        .quad   0xb5de6ecc38c11f74
+        .quad   0x654d7e9626f3c49f
+        .quad   0xe564cfdd5c7d2ceb
+        .quad   0x82eeafded737ccb9
+        .quad   0x6107db62d1f9b0ab
+        .quad   0x0b6baac3b4358dbb
+
+        // 2^180 * 6 * B
+
+        .quad   0x7ae62bcb8622fe98
+        .quad   0x47762256ceb891af
+        .quad   0x1a5a92bcf2e406b4
+        .quad   0x7d29401784e41501
+        .quad   0x204abad63700a93b
+        .quad   0xbe0023d3da779373
+        .quad   0xd85f0346633ab709
+        .quad   0x00496dc490820412
+        .quad   0x1c74b88dc27e6360
+        .quad   0x074854268d14850c
+        .quad   0xa145fb7b3e0dcb30
+        .quad   0x10843f1b43803b23
+
+        // 2^180 * 7 * B
+
+        .quad   0xc5f90455376276dd
+        .quad   0xce59158dd7645cd9
+        .quad   0x92f65d511d366b39
+        .quad   0x11574b6e526996c4
+        .quad   0xd56f672de324689b
+        .quad   0xd1da8aedb394a981
+        .quad   0xdd7b58fe9168cfed
+        .quad   0x7ce246cd4d56c1e8
+        .quad   0xb8f4308e7f80be53
+        .quad   0x5f3cb8cb34a9d397
+        .quad   0x18a961bd33cc2b2c
+        .quad   0x710045fb3a9af671
+
+        // 2^180 * 8 * B
+
+        .quad   0x73f93d36101b95eb
+        .quad   0xfaef33794f6f4486
+        .quad   0x5651735f8f15e562
+        .quad   0x7fa3f19058b40da1
+        .quad   0xa03fc862059d699e
+        .quad   0x2370cfa19a619e69
+        .quad   0xc4fe3b122f823deb
+        .quad   0x1d1b056fa7f0844e
+        .quad   0x1bc64631e56bf61f
+        .quad   0xd379ab106e5382a3
+        .quad   0x4d58c57e0540168d
+        .quad   0x566256628442d8e4
+
+        // 2^184 * 1 * B
+
+        .quad   0xb9e499def6267ff6
+        .quad   0x7772ca7b742c0843
+        .quad   0x23a0153fe9a4f2b1
+        .quad   0x2cdfdfecd5d05006
+        .quad   0xdd499cd61ff38640
+        .quad   0x29cd9bc3063625a0
+        .quad   0x51e2d8023dd73dc3
+        .quad   0x4a25707a203b9231
+        .quad   0x2ab7668a53f6ed6a
+        .quad   0x304242581dd170a1
+        .quad   0x4000144c3ae20161
+        .quad   0x5721896d248e49fc
+
+        // 2^184 * 2 * B
+
+        .quad   0x0b6e5517fd181bae
+        .quad   0x9022629f2bb963b4
+        .quad   0x5509bce932064625
+        .quad   0x578edd74f63c13da
+        .quad   0x285d5091a1d0da4e
+        .quad   0x4baa6fa7b5fe3e08
+        .quad   0x63e5177ce19393b3
+        .quad   0x03c935afc4b030fd
+        .quad   0x997276c6492b0c3d
+        .quad   0x47ccc2c4dfe205fc
+        .quad   0xdcd29b84dd623a3c
+        .quad   0x3ec2ab590288c7a2
+
+        // 2^184 * 3 * B
+
+        .quad   0xa1a0d27be4d87bb9
+        .quad   0xa98b4deb61391aed
+        .quad   0x99a0ddd073cb9b83
+        .quad   0x2dd5c25a200fcace
+        .quad   0xa7213a09ae32d1cb
+        .quad   0x0f2b87df40f5c2d5
+        .quad   0x0baea4c6e81eab29
+        .quad   0x0e1bf66c6adbac5e
+        .quad   0xe2abd5e9792c887e
+        .quad   0x1a020018cb926d5d
+        .quad   0xbfba69cdbaae5f1e
+        .quad   0x730548b35ae88f5f
+
+        // 2^184 * 4 * B
+
+        .quad   0xc43551a3cba8b8ee
+        .quad   0x65a26f1db2115f16
+        .quad   0x760f4f52ab8c3850
+        .quad   0x3043443b411db8ca
+        .quad   0x805b094ba1d6e334
+        .quad   0xbf3ef17709353f19
+        .quad   0x423f06cb0622702b
+        .quad   0x585a2277d87845dd
+        .quad   0xa18a5f8233d48962
+        .quad   0x6698c4b5ec78257f
+        .quad   0xa78e6fa5373e41ff
+        .quad   0x7656278950ef981f
+
+        // 2^184 * 5 * B
+
+        .quad   0x38c3cf59d51fc8c0
+        .quad   0x9bedd2fd0506b6f2
+        .quad   0x26bf109fab570e8f
+        .quad   0x3f4160a8c1b846a6
+        .quad   0xe17073a3ea86cf9d
+        .quad   0x3a8cfbb707155fdc
+        .quad   0x4853e7fc31838a8e
+        .quad   0x28bbf484b613f616
+        .quad   0xf2612f5c6f136c7c
+        .quad   0xafead107f6dd11be
+        .quad   0x527e9ad213de6f33
+        .quad   0x1e79cb358188f75d
+
+        // 2^184 * 6 * B
+
+        .quad   0x013436c3eef7e3f1
+        .quad   0x828b6a7ffe9e10f8
+        .quad   0x7ff908e5bcf9defc
+        .quad   0x65d7951b3a3b3831
+        .quad   0x77e953d8f5e08181
+        .quad   0x84a50c44299dded9
+        .quad   0xdc6c2d0c864525e5
+        .quad   0x478ab52d39d1f2f4
+        .quad   0x66a6a4d39252d159
+        .quad   0xe5dde1bc871ac807
+        .quad   0xb82c6b40a6c1c96f
+        .quad   0x16d87a411a212214
+
+        // 2^184 * 7 * B
+
+        .quad   0xb3bd7e5a42066215
+        .quad   0x879be3cd0c5a24c1
+        .quad   0x57c05db1d6f994b7
+        .quad   0x28f87c8165f38ca6
+        .quad   0xfba4d5e2d54e0583
+        .quad   0xe21fafd72ebd99fa
+        .quad   0x497ac2736ee9778f
+        .quad   0x1f990b577a5a6dde
+        .quad   0xa3344ead1be8f7d6
+        .quad   0x7d1e50ebacea798f
+        .quad   0x77c6569e520de052
+        .quad   0x45882fe1534d6d3e
+
+        // 2^184 * 8 * B
+
+        .quad   0x6669345d757983d6
+        .quad   0x62b6ed1117aa11a6
+        .quad   0x7ddd1857985e128f
+        .quad   0x688fe5b8f626f6dd
+        .quad   0xd8ac9929943c6fe4
+        .quad   0xb5f9f161a38392a2
+        .quad   0x2699db13bec89af3
+        .quad   0x7dcf843ce405f074
+        .quad   0x6c90d6484a4732c0
+        .quad   0xd52143fdca563299
+        .quad   0xb3be28c3915dc6e1
+        .quad   0x6739687e7327191b
+
+        // 2^188 * 1 * B
+
+        .quad   0x9f65c5ea200814cf
+        .quad   0x840536e169a31740
+        .quad   0x8b0ed13925c8b4ad
+        .quad   0x0080dbafe936361d
+        .quad   0x8ce5aad0c9cb971f
+        .quad   0x1156aaa99fd54a29
+        .quad   0x41f7247015af9b78
+        .quad   0x1fe8cca8420f49aa
+        .quad   0x72a1848f3c0cc82a
+        .quad   0x38c560c2877c9e54
+        .quad   0x5004e228ce554140
+        .quad   0x042418a103429d71
+
+        // 2^188 * 2 * B
+
+        .quad   0x899dea51abf3ff5f
+        .quad   0x9b93a8672fc2d8ba
+        .quad   0x2c38cb97be6ebd5c
+        .quad   0x114d578497263b5d
+        .quad   0x58e84c6f20816247
+        .quad   0x8db2b2b6e36fd793
+        .quad   0x977182561d484d85
+        .quad   0x0822024f8632abd7
+        .quad   0xb301bb7c6b1beca3
+        .quad   0x55393f6dc6eb1375
+        .quad   0x910d281097b6e4eb
+        .quad   0x1ad4548d9d479ea3
+
+        // 2^188 * 3 * B
+
+        .quad   0xcd5a7da0389a48fd
+        .quad   0xb38fa4aa9a78371e
+        .quad   0xc6d9761b2cdb8e6c
+        .quad   0x35cf51dbc97e1443
+        .quad   0xa06fe66d0fe9fed3
+        .quad   0xa8733a401c587909
+        .quad   0x30d14d800df98953
+        .quad   0x41ce5876c7b30258
+        .quad   0x59ac3bc5d670c022
+        .quad   0xeae67c109b119406
+        .quad   0x9798bdf0b3782fda
+        .quad   0x651e3201fd074092
+
+        // 2^188 * 4 * B
+
+        .quad   0xd63d8483ef30c5cf
+        .quad   0x4cd4b4962361cc0c
+        .quad   0xee90e500a48426ac
+        .quad   0x0af51d7d18c14eeb
+        .quad   0xa57ba4a01efcae9e
+        .quad   0x769f4beedc308a94
+        .quad   0xd1f10eeb3603cb2e
+        .quad   0x4099ce5e7e441278
+        .quad   0x1ac98e4f8a5121e9
+        .quad   0x7dae9544dbfa2fe0
+        .quad   0x8320aa0dd6430df9
+        .quad   0x667282652c4a2fb5
+
+        // 2^188 * 5 * B
+
+        .quad   0x874621f4d86bc9ab
+        .quad   0xb54c7bbe56fe6fea
+        .quad   0x077a24257fadc22c
+        .quad   0x1ab53be419b90d39
+        .quad   0xada8b6e02946db23
+        .quad   0x1c0ce51a7b253ab7
+        .quad   0x8448c85a66dd485b
+        .quad   0x7f1fc025d0675adf
+        .quad   0xd8ee1b18319ea6aa
+        .quad   0x004d88083a21f0da
+        .quad   0x3bd6aa1d883a4f4b
+        .quad   0x4db9a3a6dfd9fd14
+
+        // 2^188 * 6 * B
+
+        .quad   0x8ce7b23bb99c0755
+        .quad   0x35c5d6edc4f50f7a
+        .quad   0x7e1e2ed2ed9b50c3
+        .quad   0x36305f16e8934da1
+        .quad   0xd95b00bbcbb77c68
+        .quad   0xddbc846a91f17849
+        .quad   0x7cf700aebe28d9b3
+        .quad   0x5ce1285c85d31f3e
+        .quad   0x31b6972d98b0bde8
+        .quad   0x7d920706aca6de5b
+        .quad   0xe67310f8908a659f
+        .quad   0x50fac2a6efdf0235
+
+        // 2^188 * 7 * B
+
+        .quad   0xf3d3a9f35b880f5a
+        .quad   0xedec050cdb03e7c2
+        .quad   0xa896981ff9f0b1a2
+        .quad   0x49a4ae2bac5e34a4
+        .quad   0x295b1c86f6f449bc
+        .quad   0x51b2e84a1f0ab4dd
+        .quad   0xc001cb30aa8e551d
+        .quad   0x6a28d35944f43662
+        .quad   0x28bb12ee04a740e0
+        .quad   0x14313bbd9bce8174
+        .quad   0x72f5b5e4e8c10c40
+        .quad   0x7cbfb19936adcd5b
+
+        // 2^188 * 8 * B
+
+        .quad   0xa311ddc26b89792d
+        .quad   0x1b30b4c6da512664
+        .quad   0x0ca77b4ccf150859
+        .quad   0x1de443df1b009408
+        .quad   0x8e793a7acc36e6e0
+        .quad   0xf9fab7a37d586eed
+        .quad   0x3a4f9692bae1f4e4
+        .quad   0x1c14b03eff5f447e
+        .quad   0x19647bd114a85291
+        .quad   0x57b76cb21034d3af
+        .quad   0x6329db440f9d6dfa
+        .quad   0x5ef43e586a571493
+
+        // 2^192 * 1 * B
+
+        .quad   0xef782014385675a6
+        .quad   0xa2649f30aafda9e8
+        .quad   0x4cd1eb505cdfa8cb
+        .quad   0x46115aba1d4dc0b3
+        .quad   0xa66dcc9dc80c1ac0
+        .quad   0x97a05cf41b38a436
+        .quad   0xa7ebf3be95dbd7c6
+        .quad   0x7da0b8f68d7e7dab
+        .quad   0xd40f1953c3b5da76
+        .quad   0x1dac6f7321119e9b
+        .quad   0x03cc6021feb25960
+        .quad   0x5a5f887e83674b4b
+
+        // 2^192 * 2 * B
+
+        .quad   0x8f6301cf70a13d11
+        .quad   0xcfceb815350dd0c4
+        .quad   0xf70297d4a4bca47e
+        .quad   0x3669b656e44d1434
+        .quad   0x9e9628d3a0a643b9
+        .quad   0xb5c3cb00e6c32064
+        .quad   0x9b5302897c2dec32
+        .quad   0x43e37ae2d5d1c70c
+        .quad   0x387e3f06eda6e133
+        .quad   0x67301d5199a13ac0
+        .quad   0xbd5ad8f836263811
+        .quad   0x6a21e6cd4fd5e9be
+
+        // 2^192 * 3 * B
+
+        .quad   0xf1c6170a3046e65f
+        .quad   0x58712a2a00d23524
+        .quad   0x69dbbd3c8c82b755
+        .quad   0x586bf9f1a195ff57
+        .quad   0xef4129126699b2e3
+        .quad   0x71d30847708d1301
+        .quad   0x325432d01182b0bd
+        .quad   0x45371b07001e8b36
+        .quad   0xa6db088d5ef8790b
+        .quad   0x5278f0dc610937e5
+        .quad   0xac0349d261a16eb8
+        .quad   0x0eafb03790e52179
+
+        // 2^192 * 4 * B
+
+        .quad   0x960555c13748042f
+        .quad   0x219a41e6820baa11
+        .quad   0x1c81f73873486d0c
+        .quad   0x309acc675a02c661
+        .quad   0x5140805e0f75ae1d
+        .quad   0xec02fbe32662cc30
+        .quad   0x2cebdf1eea92396d
+        .quad   0x44ae3344c5435bb3
+        .quad   0x9cf289b9bba543ee
+        .quad   0xf3760e9d5ac97142
+        .quad   0x1d82e5c64f9360aa
+        .quad   0x62d5221b7f94678f
+
+        // 2^192 * 5 * B
+
+        .quad   0x524c299c18d0936d
+        .quad   0xc86bb56c8a0c1a0c
+        .quad   0xa375052edb4a8631
+        .quad   0x5c0efde4bc754562
+        .quad   0x7585d4263af77a3c
+        .quad   0xdfae7b11fee9144d
+        .quad   0xa506708059f7193d
+        .quad   0x14f29a5383922037
+        .quad   0xdf717edc25b2d7f5
+        .quad   0x21f970db99b53040
+        .quad   0xda9234b7c3ed4c62
+        .quad   0x5e72365c7bee093e
+
+        // 2^192 * 6 * B
+
+        .quad   0x575bfc074571217f
+        .quad   0x3779675d0694d95b
+        .quad   0x9a0a37bbf4191e33
+        .quad   0x77f1104c47b4eabc
+        .quad   0x7d9339062f08b33e
+        .quad   0x5b9659e5df9f32be
+        .quad   0xacff3dad1f9ebdfd
+        .quad   0x70b20555cb7349b7
+        .quad   0xbe5113c555112c4c
+        .quad   0x6688423a9a881fcd
+        .quad   0x446677855e503b47
+        .quad   0x0e34398f4a06404a
+
+        // 2^192 * 7 * B
+
+        .quad   0xb67d22d93ecebde8
+        .quad   0x09b3e84127822f07
+        .quad   0x743fa61fb05b6d8d
+        .quad   0x5e5405368a362372
+        .quad   0x18930b093e4b1928
+        .quad   0x7de3e10e73f3f640
+        .quad   0xf43217da73395d6f
+        .quad   0x6f8aded6ca379c3e
+        .quad   0xe340123dfdb7b29a
+        .quad   0x487b97e1a21ab291
+        .quad   0xf9967d02fde6949e
+        .quad   0x780de72ec8d3de97
+
+        // 2^192 * 8 * B
+
+        .quad   0x0ae28545089ae7bc
+        .quad   0x388ddecf1c7f4d06
+        .quad   0x38ac15510a4811b8
+        .quad   0x0eb28bf671928ce4
+        .quad   0x671feaf300f42772
+        .quad   0x8f72eb2a2a8c41aa
+        .quad   0x29a17fd797373292
+        .quad   0x1defc6ad32b587a6
+        .quad   0xaf5bbe1aef5195a7
+        .quad   0x148c1277917b15ed
+        .quad   0x2991f7fb7ae5da2e
+        .quad   0x467d201bf8dd2867
+
+        // 2^196 * 1 * B
+
+        .quad   0x7906ee72f7bd2e6b
+        .quad   0x05d270d6109abf4e
+        .quad   0x8d5cfe45b941a8a4
+        .quad   0x44c218671c974287
+        .quad   0x745f9d56296bc318
+        .quad   0x993580d4d8152e65
+        .quad   0xb0e5b13f5839e9ce
+        .quad   0x51fc2b28d43921c0
+        .quad   0x1b8fd11795e2a98c
+        .quad   0x1c4e5ee12b6b6291
+        .quad   0x5b30e7107424b572
+        .quad   0x6e6b9de84c4f4ac6
+
+        // 2^196 * 2 * B
+
+        .quad   0xdff25fce4b1de151
+        .quad   0xd841c0c7e11c4025
+        .quad   0x2554b3c854749c87
+        .quad   0x2d292459908e0df9
+        .quad   0x6b7c5f10f80cb088
+        .quad   0x736b54dc56e42151
+        .quad   0xc2b620a5c6ef99c4
+        .quad   0x5f4c802cc3a06f42
+        .quad   0x9b65c8f17d0752da
+        .quad   0x881ce338c77ee800
+        .quad   0xc3b514f05b62f9e3
+        .quad   0x66ed5dd5bec10d48
+
+        // 2^196 * 3 * B
+
+        .quad   0x7d38a1c20bb2089d
+        .quad   0x808334e196ccd412
+        .quad   0xc4a70b8c6c97d313
+        .quad   0x2eacf8bc03007f20
+        .quad   0xf0adf3c9cbca047d
+        .quad   0x81c3b2cbf4552f6b
+        .quad   0xcfda112d44735f93
+        .quad   0x1f23a0c77e20048c
+        .quad   0xf235467be5bc1570
+        .quad   0x03d2d9020dbab38c
+        .quad   0x27529aa2fcf9e09e
+        .quad   0x0840bef29d34bc50
+
+        // 2^196 * 4 * B
+
+        .quad   0x796dfb35dc10b287
+        .quad   0x27176bcd5c7ff29d
+        .quad   0x7f3d43e8c7b24905
+        .quad   0x0304f5a191c54276
+        .quad   0xcd54e06b7f37e4eb
+        .quad   0x8cc15f87f5e96cca
+        .quad   0xb8248bb0d3597dce
+        .quad   0x246affa06074400c
+        .quad   0x37d88e68fbe45321
+        .quad   0x86097548c0d75032
+        .quad   0x4e9b13ef894a0d35
+        .quad   0x25a83cac5753d325
+
+        // 2^196 * 5 * B
+
+        .quad   0x10222f48eed8165e
+        .quad   0x623fc1234b8bcf3a
+        .quad   0x1e145c09c221e8f0
+        .quad   0x7ccfa59fca782630
+        .quad   0x9f0f66293952b6e2
+        .quad   0x33db5e0e0934267b
+        .quad   0xff45252bd609fedc
+        .quad   0x06be10f5c506e0c9
+        .quad   0x1a9615a9b62a345f
+        .quad   0x22050c564a52fecc
+        .quad   0xa7a2788528bc0dfe
+        .quad   0x5e82770a1a1ee71d
+
+        // 2^196 * 6 * B
+
+        .quad   0x35425183ad896a5c
+        .quad   0xe8673afbe78d52f6
+        .quad   0x2c66f25f92a35f64
+        .quad   0x09d04f3b3b86b102
+        .quad   0xe802e80a42339c74
+        .quad   0x34175166a7fffae5
+        .quad   0x34865d1f1c408cae
+        .quad   0x2cca982c605bc5ee
+        .quad   0xfd2d5d35197dbe6e
+        .quad   0x207c2eea8be4ffa3
+        .quad   0x2613d8db325ae918
+        .quad   0x7a325d1727741d3e
+
+        // 2^196 * 7 * B
+
+        .quad   0xd036b9bbd16dfde2
+        .quad   0xa2055757c497a829
+        .quad   0x8e6cc966a7f12667
+        .quad   0x4d3b1a791239c180
+        .quad   0xecd27d017e2a076a
+        .quad   0xd788689f1636495e
+        .quad   0x52a61af0919233e5
+        .quad   0x2a479df17bb1ae64
+        .quad   0x9e5eee8e33db2710
+        .quad   0x189854ded6c43ca5
+        .quad   0xa41c22c592718138
+        .quad   0x27ad5538a43a5e9b
+
+        // 2^196 * 8 * B
+
+        .quad   0x2746dd4b15350d61
+        .quad   0xd03fcbc8ee9521b7
+        .quad   0xe86e365a138672ca
+        .quad   0x510e987f7e7d89e2
+        .quad   0xcb5a7d638e47077c
+        .quad   0x8db7536120a1c059
+        .quad   0x549e1e4d8bedfdcc
+        .quad   0x080153b7503b179d
+        .quad   0xdda69d930a3ed3e3
+        .quad   0x3d386ef1cd60a722
+        .quad   0xc817ad58bdaa4ee6
+        .quad   0x23be8d554fe7372a
+
+        // 2^200 * 1 * B
+
+        .quad   0x95fe919a74ef4fad
+        .quad   0x3a827becf6a308a2
+        .quad   0x964e01d309a47b01
+        .quad   0x71c43c4f5ba3c797
+        .quad   0xbc1ef4bd567ae7a9
+        .quad   0x3f624cb2d64498bd
+        .quad   0xe41064d22c1f4ec8
+        .quad   0x2ef9c5a5ba384001
+        .quad   0xb6fd6df6fa9e74cd
+        .quad   0xf18278bce4af267a
+        .quad   0x8255b3d0f1ef990e
+        .quad   0x5a758ca390c5f293
+
+        // 2^200 * 2 * B
+
+        .quad   0xa2b72710d9462495
+        .quad   0x3aa8c6d2d57d5003
+        .quad   0xe3d400bfa0b487ca
+        .quad   0x2dbae244b3eb72ec
+        .quad   0x8ce0918b1d61dc94
+        .quad   0x8ded36469a813066
+        .quad   0xd4e6a829afe8aad3
+        .quad   0x0a738027f639d43f
+        .quad   0x980f4a2f57ffe1cc
+        .quad   0x00670d0de1839843
+        .quad   0x105c3f4a49fb15fd
+        .quad   0x2698ca635126a69c
+
+        // 2^200 * 3 * B
+
+        .quad   0xe765318832b0ba78
+        .quad   0x381831f7925cff8b
+        .quad   0x08a81b91a0291fcc
+        .quad   0x1fb43dcc49caeb07
+        .quad   0x2e3d702f5e3dd90e
+        .quad   0x9e3f0918e4d25386
+        .quad   0x5e773ef6024da96a
+        .quad   0x3c004b0c4afa3332
+        .quad   0x9aa946ac06f4b82b
+        .quad   0x1ca284a5a806c4f3
+        .quad   0x3ed3265fc6cd4787
+        .quad   0x6b43fd01cd1fd217
+
+        // 2^200 * 4 * B
+
+        .quad   0xc7a75d4b4697c544
+        .quad   0x15fdf848df0fffbf
+        .quad   0x2868b9ebaa46785a
+        .quad   0x5a68d7105b52f714
+        .quad   0xb5c742583e760ef3
+        .quad   0x75dc52b9ee0ab990
+        .quad   0xbf1427c2072b923f
+        .quad   0x73420b2d6ff0d9f0
+        .quad   0xaf2cf6cb9e851e06
+        .quad   0x8f593913c62238c4
+        .quad   0xda8ab89699fbf373
+        .quad   0x3db5632fea34bc9e
+
+        // 2^200 * 5 * B
+
+        .quad   0xf46eee2bf75dd9d8
+        .quad   0x0d17b1f6396759a5
+        .quad   0x1bf2d131499e7273
+        .quad   0x04321adf49d75f13
+        .quad   0x2e4990b1829825d5
+        .quad   0xedeaeb873e9a8991
+        .quad   0xeef03d394c704af8
+        .quad   0x59197ea495df2b0e
+        .quad   0x04e16019e4e55aae
+        .quad   0xe77b437a7e2f92e9
+        .quad   0xc7ce2dc16f159aa4
+        .quad   0x45eafdc1f4d70cc0
+
+        // 2^200 * 6 * B
+
+        .quad   0x698401858045d72b
+        .quad   0x4c22faa2cf2f0651
+        .quad   0x941a36656b222dc6
+        .quad   0x5a5eebc80362dade
+        .quad   0xb60e4624cfccb1ed
+        .quad   0x59dbc292bd5c0395
+        .quad   0x31a09d1ddc0481c9
+        .quad   0x3f73ceea5d56d940
+        .quad   0xb7a7bfd10a4e8dc6
+        .quad   0xbe57007e44c9b339
+        .quad   0x60c1207f1557aefa
+        .quad   0x26058891266218db
+
+        // 2^200 * 7 * B
+
+        .quad   0x59f704a68360ff04
+        .quad   0xc3d93fde7661e6f4
+        .quad   0x831b2a7312873551
+        .quad   0x54ad0c2e4e615d57
+        .quad   0x4c818e3cc676e542
+        .quad   0x5e422c9303ceccad
+        .quad   0xec07cccab4129f08
+        .quad   0x0dedfa10b24443b8
+        .quad   0xee3b67d5b82b522a
+        .quad   0x36f163469fa5c1eb
+        .quad   0xa5b4d2f26ec19fd3
+        .quad   0x62ecb2baa77a9408
+
+        // 2^200 * 8 * B
+
+        .quad   0xe5ed795261152b3d
+        .quad   0x4962357d0eddd7d1
+        .quad   0x7482c8d0b96b4c71
+        .quad   0x2e59f919a966d8be
+        .quad   0x92072836afb62874
+        .quad   0x5fcd5e8579e104a5
+        .quad   0x5aad01adc630a14a
+        .quad   0x61913d5075663f98
+        .quad   0x0dc62d361a3231da
+        .quad   0xfa47583294200270
+        .quad   0x02d801513f9594ce
+        .quad   0x3ddbc2a131c05d5c
+
+        // 2^204 * 1 * B
+
+        .quad   0x3f50a50a4ffb81ef
+        .quad   0xb1e035093bf420bf
+        .quad   0x9baa8e1cc6aa2cd0
+        .quad   0x32239861fa237a40
+        .quad   0xfb735ac2004a35d1
+        .quad   0x31de0f433a6607c3
+        .quad   0x7b8591bfc528d599
+        .quad   0x55be9a25f5bb050c
+        .quad   0x0d005acd33db3dbf
+        .quad   0x0111b37c80ac35e2
+        .quad   0x4892d66c6f88ebeb
+        .quad   0x770eadb16508fbcd
+
+        // 2^204 * 2 * B
+
+        .quad   0x8451f9e05e4e89dd
+        .quad   0xc06302ffbc793937
+        .quad   0x5d22749556a6495c
+        .quad   0x09a6755ca05603fb
+        .quad   0xf1d3b681a05071b9
+        .quad   0x2207659a3592ff3a
+        .quad   0x5f0169297881e40e
+        .quad   0x16bedd0e86ba374e
+        .quad   0x5ecccc4f2c2737b5
+        .quad   0x43b79e0c2dccb703
+        .quad   0x33e008bc4ec43df3
+        .quad   0x06c1b840f07566c0
+
+        // 2^204 * 3 * B
+
+        .quad   0x7688a5c6a388f877
+        .quad   0x02a96c14deb2b6ac
+        .quad   0x64c9f3431b8c2af8
+        .quad   0x3628435554a1eed6
+        .quad   0x69ee9e7f9b02805c
+        .quad   0xcbff828a547d1640
+        .quad   0x3d93a869b2430968
+        .quad   0x46b7b8cd3fe26972
+        .quad   0xe9812086fe7eebe0
+        .quad   0x4cba6be72f515437
+        .quad   0x1d04168b516efae9
+        .quad   0x5ea1391043982cb9
+
+        // 2^204 * 4 * B
+
+        .quad   0x49125c9cf4702ee1
+        .quad   0x4520b71f8b25b32d
+        .quad   0x33193026501fef7e
+        .quad   0x656d8997c8d2eb2b
+        .quad   0x6f2b3be4d5d3b002
+        .quad   0xafec33d96a09c880
+        .quad   0x035f73a4a8bcc4cc
+        .quad   0x22c5b9284662198b
+        .quad   0xcb58c8fe433d8939
+        .quad   0x89a0cb2e6a8d7e50
+        .quad   0x79ca955309fbbe5a
+        .quad   0x0c626616cd7fc106
+
+        // 2^204 * 5 * B
+
+        .quad   0x1ffeb80a4879b61f
+        .quad   0x6396726e4ada21ed
+        .quad   0x33c7b093368025ba
+        .quad   0x471aa0c6f3c31788
+        .quad   0x8fdfc379fbf454b1
+        .quad   0x45a5a970f1a4b771
+        .quad   0xac921ef7bad35915
+        .quad   0x42d088dca81c2192
+        .quad   0x8fda0f37a0165199
+        .quad   0x0adadb77c8a0e343
+        .quad   0x20fbfdfcc875e820
+        .quad   0x1cf2bea80c2206e7
+
+        // 2^204 * 6 * B
+
+        .quad   0xc2ddf1deb36202ac
+        .quad   0x92a5fe09d2e27aa5
+        .quad   0x7d1648f6fc09f1d3
+        .quad   0x74c2cc0513bc4959
+        .quad   0x982d6e1a02c0412f
+        .quad   0x90fa4c83db58e8fe
+        .quad   0x01c2f5bcdcb18bc0
+        .quad   0x686e0c90216abc66
+        .quad   0x1fadbadba54395a7
+        .quad   0xb41a02a0ae0da66a
+        .quad   0xbf19f598bba37c07
+        .quad   0x6a12b8acde48430d
+
+        // 2^204 * 7 * B
+
+        .quad   0xf8daea1f39d495d9
+        .quad   0x592c190e525f1dfc
+        .quad   0xdb8cbd04c9991d1b
+        .quad   0x11f7fda3d88f0cb7
+        .quad   0x793bdd801aaeeb5f
+        .quad   0x00a2a0aac1518871
+        .quad   0xe8a373a31f2136b4
+        .quad   0x48aab888fc91ef19
+        .quad   0x041f7e925830f40e
+        .quad   0x002d6ca979661c06
+        .quad   0x86dc9ff92b046a2e
+        .quad   0x760360928b0493d1
+
+        // 2^204 * 8 * B
+
+        .quad   0x21bb41c6120cf9c6
+        .quad   0xeab2aa12decda59b
+        .quad   0xc1a72d020aa48b34
+        .quad   0x215d4d27e87d3b68
+        .quad   0xb43108e5695a0b05
+        .quad   0x6cb00ee8ad37a38b
+        .quad   0x5edad6eea3537381
+        .quad   0x3f2602d4b6dc3224
+        .quad   0xc8b247b65bcaf19c
+        .quad   0x49779dc3b1b2c652
+        .quad   0x89a180bbd5ece2e2
+        .quad   0x13f098a3cec8e039
+
+        // 2^208 * 1 * B
+
+        .quad   0x9adc0ff9ce5ec54b
+        .quad   0x039c2a6b8c2f130d
+        .quad   0x028007c7f0f89515
+        .quad   0x78968314ac04b36b
+        .quad   0xf3aa57a22796bb14
+        .quad   0x883abab79b07da21
+        .quad   0xe54be21831a0391c
+        .quad   0x5ee7fb38d83205f9
+        .quad   0x538dfdcb41446a8e
+        .quad   0xa5acfda9434937f9
+        .quad   0x46af908d263c8c78
+        .quad   0x61d0633c9bca0d09
+
+        // 2^208 * 2 * B
+
+        .quad   0x63744935ffdb2566
+        .quad   0xc5bd6b89780b68bb
+        .quad   0x6f1b3280553eec03
+        .quad   0x6e965fd847aed7f5
+        .quad   0xada328bcf8fc73df
+        .quad   0xee84695da6f037fc
+        .quad   0x637fb4db38c2a909
+        .quad   0x5b23ac2df8067bdc
+        .quad   0x9ad2b953ee80527b
+        .quad   0xe88f19aafade6d8d
+        .quad   0x0e711704150e82cf
+        .quad   0x79b9bbb9dd95dedc
+
+        // 2^208 * 3 * B
+
+        .quad   0xebb355406a3126c2
+        .quad   0xd26383a868c8c393
+        .quad   0x6c0c6429e5b97a82
+        .quad   0x5065f158c9fd2147
+        .quad   0xd1997dae8e9f7374
+        .quad   0xa032a2f8cfbb0816
+        .quad   0xcd6cba126d445f0a
+        .quad   0x1ba811460accb834
+        .quad   0x708169fb0c429954
+        .quad   0xe14600acd76ecf67
+        .quad   0x2eaab98a70e645ba
+        .quad   0x3981f39e58a4faf2
+
+        // 2^208 * 4 * B
+
+        .quad   0x18fb8a7559230a93
+        .quad   0x1d168f6960e6f45d
+        .quad   0x3a85a94514a93cb5
+        .quad   0x38dc083705acd0fd
+        .quad   0xc845dfa56de66fde
+        .quad   0xe152a5002c40483a
+        .quad   0xe9d2e163c7b4f632
+        .quad   0x30f4452edcbc1b65
+        .quad   0x856d2782c5759740
+        .quad   0xfa134569f99cbecc
+        .quad   0x8844fc73c0ea4e71
+        .quad   0x632d9a1a593f2469
+
+        // 2^208 * 5 * B
+
+        .quad   0xf6bb6b15b807cba6
+        .quad   0x1823c7dfbc54f0d7
+        .quad   0xbb1d97036e29670b
+        .quad   0x0b24f48847ed4a57
+        .quad   0xbf09fd11ed0c84a7
+        .quad   0x63f071810d9f693a
+        .quad   0x21908c2d57cf8779
+        .quad   0x3a5a7df28af64ba2
+        .quad   0xdcdad4be511beac7
+        .quad   0xa4538075ed26ccf2
+        .quad   0xe19cff9f005f9a65
+        .quad   0x34fcf74475481f63
+
+        // 2^208 * 6 * B
+
+        .quad   0xc197e04c789767ca
+        .quad   0xb8714dcb38d9467d
+        .quad   0x55de888283f95fa8
+        .quad   0x3d3bdc164dfa63f7
+        .quad   0xa5bb1dab78cfaa98
+        .quad   0x5ceda267190b72f2
+        .quad   0x9309c9110a92608e
+        .quad   0x0119a3042fb374b0
+        .quad   0x67a2d89ce8c2177d
+        .quad   0x669da5f66895d0c1
+        .quad   0xf56598e5b282a2b0
+        .quad   0x56c088f1ede20a73
+
+        // 2^208 * 7 * B
+
+        .quad   0x336d3d1110a86e17
+        .quad   0xd7f388320b75b2fa
+        .quad   0xf915337625072988
+        .quad   0x09674c6b99108b87
+        .quad   0x581b5fac24f38f02
+        .quad   0xa90be9febae30cbd
+        .quad   0x9a2169028acf92f0
+        .quad   0x038b7ea48359038f
+        .quad   0x9f4ef82199316ff8
+        .quad   0x2f49d282eaa78d4f
+        .quad   0x0971a5ab5aef3174
+        .quad   0x6e5e31025969eb65
+
+        // 2^208 * 8 * B
+
+        .quad   0xb16c62f587e593fb
+        .quad   0x4999eddeca5d3e71
+        .quad   0xb491c1e014cc3e6d
+        .quad   0x08f5114789a8dba8
+        .quad   0x3304fb0e63066222
+        .quad   0xfb35068987acba3f
+        .quad   0xbd1924778c1061a3
+        .quad   0x3058ad43d1838620
+        .quad   0x323c0ffde57663d0
+        .quad   0x05c3df38a22ea610
+        .quad   0xbdc78abdac994f9a
+        .quad   0x26549fa4efe3dc99
+
+        // 2^212 * 1 * B
+
+        .quad   0x738b38d787ce8f89
+        .quad   0xb62658e24179a88d
+        .quad   0x30738c9cf151316d
+        .quad   0x49128c7f727275c9
+        .quad   0x04dbbc17f75396b9
+        .quad   0x69e6a2d7d2f86746
+        .quad   0xc6409d99f53eabc6
+        .quad   0x606175f6332e25d2
+        .quad   0x4021370ef540e7dd
+        .quad   0x0910d6f5a1f1d0a5
+        .quad   0x4634aacd5b06b807
+        .quad   0x6a39e6356944f235
+
+        // 2^212 * 2 * B
+
+        .quad   0x96cd5640df90f3e7
+        .quad   0x6c3a760edbfa25ea
+        .quad   0x24f3ef0959e33cc4
+        .quad   0x42889e7e530d2e58
+        .quad   0x1da1965774049e9d
+        .quad   0xfbcd6ea198fe352b
+        .quad   0xb1cbcd50cc5236a6
+        .quad   0x1f5ec83d3f9846e2
+        .quad   0x8efb23c3328ccb75
+        .quad   0xaf42a207dd876ee9
+        .quad   0x20fbdadc5dfae796
+        .quad   0x241e246b06bf9f51
+
+        // 2^212 * 3 * B
+
+        .quad   0x29e68e57ad6e98f6
+        .quad   0x4c9260c80b462065
+        .quad   0x3f00862ea51ebb4b
+        .quad   0x5bc2c77fb38d9097
+        .quad   0x7eaafc9a6280bbb8
+        .quad   0x22a70f12f403d809
+        .quad   0x31ce40bb1bfc8d20
+        .quad   0x2bc65635e8bd53ee
+        .quad   0xe8d5dc9fa96bad93
+        .quad   0xe58fb17dde1947dc
+        .quad   0x681532ea65185fa3
+        .quad   0x1fdd6c3b034a7830
+
+        // 2^212 * 4 * B
+
+        .quad   0x0a64e28c55dc18fe
+        .quad   0xe3df9e993399ebdd
+        .quad   0x79ac432370e2e652
+        .quad   0x35ff7fc33ae4cc0e
+        .quad   0x9c13a6a52dd8f7a9
+        .quad   0x2dbb1f8c3efdcabf
+        .quad   0x961e32405e08f7b5
+        .quad   0x48c8a121bbe6c9e5
+        .quad   0xfc415a7c59646445
+        .quad   0xd224b2d7c128b615
+        .quad   0x6035c9c905fbb912
+        .quad   0x42d7a91274429fab
+
+        // 2^212 * 5 * B
+
+        .quad   0x4e6213e3eaf72ed3
+        .quad   0x6794981a43acd4e7
+        .quad   0xff547cde6eb508cb
+        .quad   0x6fed19dd10fcb532
+        .quad   0xa9a48947933da5bc
+        .quad   0x4a58920ec2e979ec
+        .quad   0x96d8800013e5ac4c
+        .quad   0x453692d74b48b147
+        .quad   0xdd775d99a8559c6f
+        .quad   0xf42a2140df003e24
+        .quad   0x5223e229da928a66
+        .quad   0x063f46ba6d38f22c
+
+        // 2^212 * 6 * B
+
+        .quad   0xd2d242895f536694
+        .quad   0xca33a2c542939b2c
+        .quad   0x986fada6c7ddb95c
+        .quad   0x5a152c042f712d5d
+        .quad   0x39843cb737346921
+        .quad   0xa747fb0738c89447
+        .quad   0xcb8d8031a245307e
+        .quad   0x67810f8e6d82f068
+        .quad   0x3eeb8fbcd2287db4
+        .quad   0x72c7d3a301a03e93
+        .quad   0x5473e88cbd98265a
+        .quad   0x7324aa515921b403
+
+        // 2^212 * 7 * B
+
+        .quad   0x857942f46c3cbe8e
+        .quad   0xa1d364b14730c046
+        .quad   0x1c8ed914d23c41bf
+        .quad   0x0838e161eef6d5d2
+        .quad   0xad23f6dae82354cb
+        .quad   0x6962502ab6571a6d
+        .quad   0x9b651636e38e37d1
+        .quad   0x5cac5005d1a3312f
+        .quad   0x8cc154cce9e39904
+        .quad   0x5b3a040b84de6846
+        .quad   0xc4d8a61cb1be5d6e
+        .quad   0x40fb897bd8861f02
+
+        // 2^212 * 8 * B
+
+        .quad   0x84c5aa9062de37a1
+        .quad   0x421da5000d1d96e1
+        .quad   0x788286306a9242d9
+        .quad   0x3c5e464a690d10da
+        .quad   0xe57ed8475ab10761
+        .quad   0x71435e206fd13746
+        .quad   0x342f824ecd025632
+        .quad   0x4b16281ea8791e7b
+        .quad   0xd1c101d50b813381
+        .quad   0xdee60f1176ee6828
+        .quad   0x0cb68893383f6409
+        .quad   0x6183c565f6ff484a
+
+        // 2^216 * 1 * B
+
+        .quad   0x741d5a461e6bf9d6
+        .quad   0x2305b3fc7777a581
+        .quad   0xd45574a26474d3d9
+        .quad   0x1926e1dc6401e0ff
+        .quad   0xdb468549af3f666e
+        .quad   0xd77fcf04f14a0ea5
+        .quad   0x3df23ff7a4ba0c47
+        .quad   0x3a10dfe132ce3c85
+        .quad   0xe07f4e8aea17cea0
+        .quad   0x2fd515463a1fc1fd
+        .quad   0x175322fd31f2c0f1
+        .quad   0x1fa1d01d861e5d15
+
+        // 2^216 * 2 * B
+
+        .quad   0xcc8055947d599832
+        .quad   0x1e4656da37f15520
+        .quad   0x99f6f7744e059320
+        .quad   0x773563bc6a75cf33
+        .quad   0x38dcac00d1df94ab
+        .quad   0x2e712bddd1080de9
+        .quad   0x7f13e93efdd5e262
+        .quad   0x73fced18ee9a01e5
+        .quad   0x06b1e90863139cb3
+        .quad   0xa493da67c5a03ecd
+        .quad   0x8d77cec8ad638932
+        .quad   0x1f426b701b864f44
+
+        // 2^216 * 3 * B
+
+        .quad   0xefc9264c41911c01
+        .quad   0xf1a3b7b817a22c25
+        .quad   0x5875da6bf30f1447
+        .quad   0x4e1af5271d31b090
+        .quad   0xf17e35c891a12552
+        .quad   0xb76b8153575e9c76
+        .quad   0xfa83406f0d9b723e
+        .quad   0x0b76bb1b3fa7e438
+        .quad   0x08b8c1f97f92939b
+        .quad   0xbe6771cbd444ab6e
+        .quad   0x22e5646399bb8017
+        .quad   0x7b6dd61eb772a955
+
+        // 2^216 * 4 * B
+
+        .quad   0xb7adc1e850f33d92
+        .quad   0x7998fa4f608cd5cf
+        .quad   0xad962dbd8dfc5bdb
+        .quad   0x703e9bceaf1d2f4f
+        .quad   0x5730abf9ab01d2c7
+        .quad   0x16fb76dc40143b18
+        .quad   0x866cbe65a0cbb281
+        .quad   0x53fa9b659bff6afe
+        .quad   0x6c14c8e994885455
+        .quad   0x843a5d6665aed4e5
+        .quad   0x181bb73ebcd65af1
+        .quad   0x398d93e5c4c61f50
+
+        // 2^216 * 5 * B
+
+        .quad   0x1c4bd16733e248f3
+        .quad   0xbd9e128715bf0a5f
+        .quad   0xd43f8cf0a10b0376
+        .quad   0x53b09b5ddf191b13
+        .quad   0xc3877c60d2e7e3f2
+        .quad   0x3b34aaa030828bb1
+        .quad   0x283e26e7739ef138
+        .quad   0x699c9c9002c30577
+        .quad   0xf306a7235946f1cc
+        .quad   0x921718b5cce5d97d
+        .quad   0x28cdd24781b4e975
+        .quad   0x51caf30c6fcdd907
+
+        // 2^216 * 6 * B
+
+        .quad   0xa60ba7427674e00a
+        .quad   0x630e8570a17a7bf3
+        .quad   0x3758563dcf3324cc
+        .quad   0x5504aa292383fdaa
+        .quad   0x737af99a18ac54c7
+        .quad   0x903378dcc51cb30f
+        .quad   0x2b89bc334ce10cc7
+        .quad   0x12ae29c189f8e99a
+        .quad   0xa99ec0cb1f0d01cf
+        .quad   0x0dd1efcc3a34f7ae
+        .quad   0x55ca7521d09c4e22
+        .quad   0x5fd14fe958eba5ea
+
+        // 2^216 * 7 * B
+
+        .quad   0xb5dc2ddf2845ab2c
+        .quad   0x069491b10a7fe993
+        .quad   0x4daaf3d64002e346
+        .quad   0x093ff26e586474d1
+        .quad   0x3c42fe5ebf93cb8e
+        .quad   0xbedfa85136d4565f
+        .quad   0xe0f0859e884220e8
+        .quad   0x7dd73f960725d128
+        .quad   0xb10d24fe68059829
+        .quad   0x75730672dbaf23e5
+        .quad   0x1367253ab457ac29
+        .quad   0x2f59bcbc86b470a4
+
+        // 2^216 * 8 * B
+
+        .quad   0x83847d429917135f
+        .quad   0xad1b911f567d03d7
+        .quad   0x7e7748d9be77aad1
+        .quad   0x5458b42e2e51af4a
+        .quad   0x7041d560b691c301
+        .quad   0x85201b3fadd7e71e
+        .quad   0x16c2e16311335585
+        .quad   0x2aa55e3d010828b1
+        .quad   0xed5192e60c07444f
+        .quad   0x42c54e2d74421d10
+        .quad   0x352b4c82fdb5c864
+        .quad   0x13e9004a8a768664
+
+        // 2^220 * 1 * B
+
+        .quad   0xcbb5b5556c032bff
+        .quad   0xdf7191b729297a3a
+        .quad   0xc1ff7326aded81bb
+        .quad   0x71ade8bb68be03f5
+        .quad   0x1e6284c5806b467c
+        .quad   0xc5f6997be75d607b
+        .quad   0x8b67d958b378d262
+        .quad   0x3d88d66a81cd8b70
+        .quad   0x8b767a93204ed789
+        .quad   0x762fcacb9fa0ae2a
+        .quad   0x771febcc6dce4887
+        .quad   0x343062158ff05fb3
+
+        // 2^220 * 2 * B
+
+        .quad   0xe05da1a7e1f5bf49
+        .quad   0x26457d6dd4736092
+        .quad   0x77dcb07773cc32f6
+        .quad   0x0a5d94969cdd5fcd
+        .quad   0xfce219072a7b31b4
+        .quad   0x4d7adc75aa578016
+        .quad   0x0ec276a687479324
+        .quad   0x6d6d9d5d1fda4beb
+        .quad   0x22b1a58ae9b08183
+        .quad   0xfd95d071c15c388b
+        .quad   0xa9812376850a0517
+        .quad   0x33384cbabb7f335e
+
+        // 2^220 * 3 * B
+
+        .quad   0x3c6fa2680ca2c7b5
+        .quad   0x1b5082046fb64fda
+        .quad   0xeb53349c5431d6de
+        .quad   0x5278b38f6b879c89
+        .quad   0x33bc627a26218b8d
+        .quad   0xea80b21fc7a80c61
+        .quad   0x9458b12b173e9ee6
+        .quad   0x076247be0e2f3059
+        .quad   0x52e105f61416375a
+        .quad   0xec97af3685abeba4
+        .quad   0x26e6b50623a67c36
+        .quad   0x5cf0e856f3d4fb01
+
+        // 2^220 * 4 * B
+
+        .quad   0xf6c968731ae8cab4
+        .quad   0x5e20741ecb4f92c5
+        .quad   0x2da53be58ccdbc3e
+        .quad   0x2dddfea269970df7
+        .quad   0xbeaece313db342a8
+        .quad   0xcba3635b842db7ee
+        .quad   0xe88c6620817f13ef
+        .quad   0x1b9438aa4e76d5c6
+        .quad   0x8a50777e166f031a
+        .quad   0x067b39f10fb7a328
+        .quad   0x1925c9a6010fbd76
+        .quad   0x6df9b575cc740905
+
+        // 2^220 * 5 * B
+
+        .quad   0x42c1192927f6bdcf
+        .quad   0x8f91917a403d61ca
+        .quad   0xdc1c5a668b9e1f61
+        .quad   0x1596047804ec0f8d
+        .quad   0xecdfc35b48cade41
+        .quad   0x6a88471fb2328270
+        .quad   0x740a4a2440a01b6a
+        .quad   0x471e5796003b5f29
+        .quad   0xda96bbb3aced37ac
+        .quad   0x7a2423b5e9208cea
+        .quad   0x24cc5c3038aebae2
+        .quad   0x50c356afdc5dae2f
+
+        // 2^220 * 6 * B
+
+        .quad   0x09dcbf4341c30318
+        .quad   0xeeba061183181dce
+        .quad   0xc179c0cedc1e29a1
+        .quad   0x1dbf7b89073f35b0
+        .quad   0xcfed9cdf1b31b964
+        .quad   0xf486a9858ca51af3
+        .quad   0x14897265ea8c1f84
+        .quad   0x784a53dd932acc00
+        .quad   0x2d99f9df14fc4920
+        .quad   0x76ccb60cc4499fe5
+        .quad   0xa4132cbbe5cf0003
+        .quad   0x3f93d82354f000ea
+
+        // 2^220 * 7 * B
+
+        .quad   0x8183e7689e04ce85
+        .quad   0x678fb71e04465341
+        .quad   0xad92058f6688edac
+        .quad   0x5da350d3532b099a
+        .quad   0xeaac12d179e14978
+        .quad   0xff923ff3bbebff5e
+        .quad   0x4af663e40663ce27
+        .quad   0x0fd381a811a5f5ff
+        .quad   0xf256aceca436df54
+        .quad   0x108b6168ae69d6e8
+        .quad   0x20d986cb6b5d036c
+        .quad   0x655957b9fee2af50
+
+        // 2^220 * 8 * B
+
+        .quad   0xaea8b07fa902030f
+        .quad   0xf88c766af463d143
+        .quad   0x15b083663c787a60
+        .quad   0x08eab1148267a4a8
+        .quad   0xbdc1409bd002d0ac
+        .quad   0x66660245b5ccd9a6
+        .quad   0x82317dc4fade85ec
+        .quad   0x02fe934b6ad7df0d
+        .quad   0xef5cf100cfb7ea74
+        .quad   0x22897633a1cb42ac
+        .quad   0xd4ce0c54cef285e2
+        .quad   0x30408c048a146a55
+
+        // 2^224 * 1 * B
+
+        .quad   0x739d8845832fcedb
+        .quad   0xfa38d6c9ae6bf863
+        .quad   0x32bc0dcab74ffef7
+        .quad   0x73937e8814bce45e
+        .quad   0xbb2e00c9193b877f
+        .quad   0xece3a890e0dc506b
+        .quad   0xecf3b7c036de649f
+        .quad   0x5f46040898de9e1a
+        .quad   0xb9037116297bf48d
+        .quad   0xa9d13b22d4f06834
+        .quad   0xe19715574696bdc6
+        .quad   0x2cf8a4e891d5e835
+
+        // 2^224 * 2 * B
+
+        .quad   0x6d93fd8707110f67
+        .quad   0xdd4c09d37c38b549
+        .quad   0x7cb16a4cc2736a86
+        .quad   0x2049bd6e58252a09
+        .quad   0x2cb5487e17d06ba2
+        .quad   0x24d2381c3950196b
+        .quad   0xd7659c8185978a30
+        .quad   0x7a6f7f2891d6a4f6
+        .quad   0x7d09fd8d6a9aef49
+        .quad   0xf0ee60be5b3db90b
+        .quad   0x4c21b52c519ebfd4
+        .quad   0x6011aadfc545941d
+
+        // 2^224 * 3 * B
+
+        .quad   0x5f67926dcf95f83c
+        .quad   0x7c7e856171289071
+        .quad   0xd6a1e7f3998f7a5b
+        .quad   0x6fc5cc1b0b62f9e0
+        .quad   0x63ded0c802cbf890
+        .quad   0xfbd098ca0dff6aaa
+        .quad   0x624d0afdb9b6ed99
+        .quad   0x69ce18b779340b1e
+        .quad   0xd1ef5528b29879cb
+        .quad   0xdd1aae3cd47e9092
+        .quad   0x127e0442189f2352
+        .quad   0x15596b3ae57101f1
+
+        // 2^224 * 4 * B
+
+        .quad   0x462739d23f9179a2
+        .quad   0xff83123197d6ddcf
+        .quad   0x1307deb553f2148a
+        .quad   0x0d2237687b5f4dda
+        .quad   0x09ff31167e5124ca
+        .quad   0x0be4158bd9c745df
+        .quad   0x292b7d227ef556e5
+        .quad   0x3aa4e241afb6d138
+        .quad   0x2cc138bf2a3305f5
+        .quad   0x48583f8fa2e926c3
+        .quad   0x083ab1a25549d2eb
+        .quad   0x32fcaa6e4687a36c
+
+        // 2^224 * 5 * B
+
+        .quad   0x7bc56e8dc57d9af5
+        .quad   0x3e0bd2ed9df0bdf2
+        .quad   0xaac014de22efe4a3
+        .quad   0x4627e9cefebd6a5c
+        .quad   0x3207a4732787ccdf
+        .quad   0x17e31908f213e3f8
+        .quad   0xd5b2ecd7f60d964e
+        .quad   0x746f6336c2600be9
+        .quad   0x3f4af345ab6c971c
+        .quad   0xe288eb729943731f
+        .quad   0x33596a8a0344186d
+        .quad   0x7b4917007ed66293
+
+        // 2^224 * 6 * B
+
+        .quad   0x2d85fb5cab84b064
+        .quad   0x497810d289f3bc14
+        .quad   0x476adc447b15ce0c
+        .quad   0x122ba376f844fd7b
+        .quad   0x54341b28dd53a2dd
+        .quad   0xaa17905bdf42fc3f
+        .quad   0x0ff592d94dd2f8f4
+        .quad   0x1d03620fe08cd37d
+        .quad   0xc20232cda2b4e554
+        .quad   0x9ed0fd42115d187f
+        .quad   0x2eabb4be7dd479d9
+        .quad   0x02c70bf52b68ec4c
+
+        // 2^224 * 7 * B
+
+        .quad   0xa287ec4b5d0b2fbb
+        .quad   0x415c5790074882ca
+        .quad   0xe044a61ec1d0815c
+        .quad   0x26334f0a409ef5e0
+        .quad   0xace532bf458d72e1
+        .quad   0x5be768e07cb73cb5
+        .quad   0x56cf7d94ee8bbde7
+        .quad   0x6b0697e3feb43a03
+        .quad   0xb6c8f04adf62a3c0
+        .quad   0x3ef000ef076da45d
+        .quad   0x9c9cb95849f0d2a9
+        .quad   0x1cc37f43441b2fae
+
+        // 2^224 * 8 * B
+
+        .quad   0x508f565a5cc7324f
+        .quad   0xd061c4c0e506a922
+        .quad   0xfb18abdb5c45ac19
+        .quad   0x6c6809c10380314a
+        .quad   0xd76656f1c9ceaeb9
+        .quad   0x1c5b15f818e5656a
+        .quad   0x26e72832844c2334
+        .quad   0x3a346f772f196838
+        .quad   0xd2d55112e2da6ac8
+        .quad   0xe9bd0331b1e851ed
+        .quad   0x960746dd8ec67262
+        .quad   0x05911b9f6ef7c5d0
+
+        // 2^228 * 1 * B
+
+        .quad   0xe9dcd756b637ff2d
+        .quad   0xec4c348fc987f0c4
+        .quad   0xced59285f3fbc7b7
+        .quad   0x3305354793e1ea87
+        .quad   0x01c18980c5fe9f94
+        .quad   0xcd656769716fd5c8
+        .quad   0x816045c3d195a086
+        .quad   0x6e2b7f3266cc7982
+        .quad   0xcc802468f7c3568f
+        .quad   0x9de9ba8219974cb3
+        .quad   0xabb7229cb5b81360
+        .quad   0x44e2017a6fbeba62
+
+        // 2^228 * 2 * B
+
+        .quad   0xc4c2a74354dab774
+        .quad   0x8e5d4c3c4eaf031a
+        .quad   0xb76c23d242838f17
+        .quad   0x749a098f68dce4ea
+        .quad   0x87f82cf3b6ca6ecd
+        .quad   0x580f893e18f4a0c2
+        .quad   0x058930072604e557
+        .quad   0x6cab6ac256d19c1d
+        .quad   0xdcdfe0a02cc1de60
+        .quad   0x032665ff51c5575b
+        .quad   0x2c0c32f1073abeeb
+        .quad   0x6a882014cd7b8606
+
+        // 2^228 * 3 * B
+
+        .quad   0xa52a92fea4747fb5
+        .quad   0xdc12a4491fa5ab89
+        .quad   0xd82da94bb847a4ce
+        .quad   0x4d77edce9512cc4e
+        .quad   0xd111d17caf4feb6e
+        .quad   0x050bba42b33aa4a3
+        .quad   0x17514c3ceeb46c30
+        .quad   0x54bedb8b1bc27d75
+        .quad   0x77c8e14577e2189c
+        .quad   0xa3e46f6aff99c445
+        .quad   0x3144dfc86d335343
+        .quad   0x3a96559e7c4216a9
+
+        // 2^228 * 4 * B
+
+        .quad   0x12550d37f42ad2ee
+        .quad   0x8b78e00498a1fbf5
+        .quad   0x5d53078233894cb2
+        .quad   0x02c84e4e3e498d0c
+        .quad   0x4493896880baaa52
+        .quad   0x4c98afc4f285940e
+        .quad   0xef4aa79ba45448b6
+        .quad   0x5278c510a57aae7f
+        .quad   0xa54dd074294c0b94
+        .quad   0xf55d46b8df18ffb6
+        .quad   0xf06fecc58dae8366
+        .quad   0x588657668190d165
+
+        // 2^228 * 5 * B
+
+        .quad   0xd47712311aef7117
+        .quad   0x50343101229e92c7
+        .quad   0x7a95e1849d159b97
+        .quad   0x2449959b8b5d29c9
+        .quad   0xbf5834f03de25cc3
+        .quad   0xb887c8aed6815496
+        .quad   0x5105221a9481e892
+        .quad   0x6760ed19f7723f93
+        .quad   0x669ba3b7ac35e160
+        .quad   0x2eccf73fba842056
+        .quad   0x1aec1f17c0804f07
+        .quad   0x0d96bc031856f4e7
+
+        // 2^228 * 6 * B
+
+        .quad   0x3318be7775c52d82
+        .quad   0x4cb764b554d0aab9
+        .quad   0xabcf3d27cc773d91
+        .quad   0x3bf4d1848123288a
+        .quad   0xb1d534b0cc7505e1
+        .quad   0x32cd003416c35288
+        .quad   0xcb36a5800762c29d
+        .quad   0x5bfe69b9237a0bf8
+        .quad   0x183eab7e78a151ab
+        .quad   0xbbe990c999093763
+        .quad   0xff717d6e4ac7e335
+        .quad   0x4c5cddb325f39f88
+
+        // 2^228 * 7 * B
+
+        .quad   0xc0f6b74d6190a6eb
+        .quad   0x20ea81a42db8f4e4
+        .quad   0xa8bd6f7d97315760
+        .quad   0x33b1d60262ac7c21
+        .quad   0x57750967e7a9f902
+        .quad   0x2c37fdfc4f5b467e
+        .quad   0xb261663a3177ba46
+        .quad   0x3a375e78dc2d532b
+        .quad   0x8141e72f2d4dddea
+        .quad   0xe6eafe9862c607c8
+        .quad   0x23c28458573cafd0
+        .quad   0x46b9476f4ff97346
+
+        // 2^228 * 8 * B
+
+        .quad   0x0c1ffea44f901e5c
+        .quad   0x2b0b6fb72184b782
+        .quad   0xe587ff910114db88
+        .quad   0x37130f364785a142
+        .quad   0x1215505c0d58359f
+        .quad   0x2a2013c7fc28c46b
+        .quad   0x24a0a1af89ea664e
+        .quad   0x4400b638a1130e1f
+        .quad   0x3a01b76496ed19c3
+        .quad   0x31e00ab0ed327230
+        .quad   0x520a885783ca15b1
+        .quad   0x06aab9875accbec7
+
+        // 2^232 * 1 * B
+
+        .quad   0xc1339983f5df0ebb
+        .quad   0xc0f3758f512c4cac
+        .quad   0x2cf1130a0bb398e1
+        .quad   0x6b3cecf9aa270c62
+        .quad   0x5349acf3512eeaef
+        .quad   0x20c141d31cc1cb49
+        .quad   0x24180c07a99a688d
+        .quad   0x555ef9d1c64b2d17
+        .quad   0x36a770ba3b73bd08
+        .quad   0x624aef08a3afbf0c
+        .quad   0x5737ff98b40946f2
+        .quad   0x675f4de13381749d
+
+        // 2^232 * 2 * B
+
+        .quad   0x0e2c52036b1782fc
+        .quad   0x64816c816cad83b4
+        .quad   0xd0dcbdd96964073e
+        .quad   0x13d99df70164c520
+        .quad   0xa12ff6d93bdab31d
+        .quad   0x0725d80f9d652dfe
+        .quad   0x019c4ff39abe9487
+        .quad   0x60f450b882cd3c43
+        .quad   0x014b5ec321e5c0ca
+        .quad   0x4fcb69c9d719bfa2
+        .quad   0x4e5f1c18750023a0
+        .quad   0x1c06de9e55edac80
+
+        // 2^232 * 3 * B
+
+        .quad   0x990f7ad6a33ec4e2
+        .quad   0x6608f938be2ee08e
+        .quad   0x9ca143c563284515
+        .quad   0x4cf38a1fec2db60d
+        .quad   0xffd52b40ff6d69aa
+        .quad   0x34530b18dc4049bb
+        .quad   0x5e4a5c2fa34d9897
+        .quad   0x78096f8e7d32ba2d
+        .quad   0xa0aaaa650dfa5ce7
+        .quad   0xf9c49e2a48b5478c
+        .quad   0x4f09cc7d7003725b
+        .quad   0x373cad3a26091abe
+
+        // 2^232 * 4 * B
+
+        .quad   0xb294634d82c9f57c
+        .quad   0x1fcbfde124934536
+        .quad   0x9e9c4db3418cdb5a
+        .quad   0x0040f3d9454419fc
+        .quad   0xf1bea8fb89ddbbad
+        .quad   0x3bcb2cbc61aeaecb
+        .quad   0x8f58a7bb1f9b8d9d
+        .quad   0x21547eda5112a686
+        .quad   0xdefde939fd5986d3
+        .quad   0xf4272c89510a380c
+        .quad   0xb72ba407bb3119b9
+        .quad   0x63550a334a254df4
+
+        // 2^232 * 5 * B
+
+        .quad   0x6507d6edb569cf37
+        .quad   0x178429b00ca52ee1
+        .quad   0xea7c0090eb6bd65d
+        .quad   0x3eea62c7daf78f51
+        .quad   0x9bba584572547b49
+        .quad   0xf305c6fae2c408e0
+        .quad   0x60e8fa69c734f18d
+        .quad   0x39a92bafaa7d767a
+        .quad   0x9d24c713e693274e
+        .quad   0x5f63857768dbd375
+        .quad   0x70525560eb8ab39a
+        .quad   0x68436a0665c9c4cd
+
+        // 2^232 * 6 * B
+
+        .quad   0xbc0235e8202f3f27
+        .quad   0xc75c00e264f975b0
+        .quad   0x91a4e9d5a38c2416
+        .quad   0x17b6e7f68ab789f9
+        .quad   0x1e56d317e820107c
+        .quad   0xc5266844840ae965
+        .quad   0xc1e0a1c6320ffc7a
+        .quad   0x5373669c91611472
+        .quad   0x5d2814ab9a0e5257
+        .quad   0x908f2084c9cab3fc
+        .quad   0xafcaf5885b2d1eca
+        .quad   0x1cb4b5a678f87d11
+
+        // 2^232 * 7 * B
+
+        .quad   0xb664c06b394afc6c
+        .quad   0x0c88de2498da5fb1
+        .quad   0x4f8d03164bcad834
+        .quad   0x330bca78de7434a2
+        .quad   0x6b74aa62a2a007e7
+        .quad   0xf311e0b0f071c7b1
+        .quad   0x5707e438000be223
+        .quad   0x2dc0fd2d82ef6eac
+        .quad   0x982eff841119744e
+        .quad   0xf9695e962b074724
+        .quad   0xc58ac14fbfc953fb
+        .quad   0x3c31be1b369f1cf5
+
+        // 2^232 * 8 * B
+
+        .quad   0xb0f4864d08948aee
+        .quad   0x07dc19ee91ba1c6f
+        .quad   0x7975cdaea6aca158
+        .quad   0x330b61134262d4bb
+        .quad   0xc168bc93f9cb4272
+        .quad   0xaeb8711fc7cedb98
+        .quad   0x7f0e52aa34ac8d7a
+        .quad   0x41cec1097e7d55bb
+        .quad   0xf79619d7a26d808a
+        .quad   0xbb1fd49e1d9e156d
+        .quad   0x73d7c36cdba1df27
+        .quad   0x26b44cd91f28777d
+
+        // 2^236 * 1 * B
+
+        .quad   0x300a9035393aa6d8
+        .quad   0x2b501131a12bb1cd
+        .quad   0x7b1ff677f093c222
+        .quad   0x4309c1f8cab82bad
+        .quad   0xaf44842db0285f37
+        .quad   0x8753189047efc8df
+        .quad   0x9574e091f820979a
+        .quad   0x0e378d6069615579
+        .quad   0xd9fa917183075a55
+        .quad   0x4bdb5ad26b009fdc
+        .quad   0x7829ad2cd63def0e
+        .quad   0x078fc54975fd3877
+
+        // 2^236 * 2 * B
+
+        .quad   0x87dfbd1428878f2d
+        .quad   0x134636dd1e9421a1
+        .quad   0x4f17c951257341a3
+        .quad   0x5df98d4bad296cb8
+        .quad   0xe2004b5bb833a98a
+        .quad   0x44775dec2d4c3330
+        .quad   0x3aa244067eace913
+        .quad   0x272630e3d58e00a9
+        .quad   0xf3678fd0ecc90b54
+        .quad   0xf001459b12043599
+        .quad   0x26725fbc3758b89b
+        .quad   0x4325e4aa73a719ae
+
+        // 2^236 * 3 * B
+
+        .quad   0x657dc6ef433c3493
+        .quad   0x65375e9f80dbf8c3
+        .quad   0x47fd2d465b372dae
+        .quad   0x4966ab79796e7947
+        .quad   0xed24629acf69f59d
+        .quad   0x2a4a1ccedd5abbf4
+        .quad   0x3535ca1f56b2d67b
+        .quad   0x5d8c68d043b1b42d
+        .quad   0xee332d4de3b42b0a
+        .quad   0xd84e5a2b16a4601c
+        .quad   0x78243877078ba3e4
+        .quad   0x77ed1eb4184ee437
+
+        // 2^236 * 4 * B
+
+        .quad   0xbfd4e13f201839a0
+        .quad   0xaeefffe23e3df161
+        .quad   0xb65b04f06b5d1fe3
+        .quad   0x52e085fb2b62fbc0
+        .quad   0x185d43f89e92ed1a
+        .quad   0xb04a1eeafe4719c6
+        .quad   0x499fbe88a6f03f4f
+        .quad   0x5d8b0d2f3c859bdd
+        .quad   0x124079eaa54cf2ba
+        .quad   0xd72465eb001b26e7
+        .quad   0x6843bcfdc97af7fd
+        .quad   0x0524b42b55eacd02
+
+        // 2^236 * 5 * B
+
+        .quad   0xfd0d5dbee45447b0
+        .quad   0x6cec351a092005ee
+        .quad   0x99a47844567579cb
+        .quad   0x59d242a216e7fa45
+        .quad   0xbc18dcad9b829eac
+        .quad   0x23ae7d28b5f579d0
+        .quad   0xc346122a69384233
+        .quad   0x1a6110b2e7d4ac89
+        .quad   0x4f833f6ae66997ac
+        .quad   0x6849762a361839a4
+        .quad   0x6985dec1970ab525
+        .quad   0x53045e89dcb1f546
+
+        // 2^236 * 6 * B
+
+        .quad   0xcb8bb346d75353db
+        .quad   0xfcfcb24bae511e22
+        .quad   0xcba48d40d50ae6ef
+        .quad   0x26e3bae5f4f7cb5d
+        .quad   0x84da3cde8d45fe12
+        .quad   0xbd42c218e444e2d2
+        .quad   0xa85196781f7e3598
+        .quad   0x7642c93f5616e2b2
+        .quad   0x2323daa74595f8e4
+        .quad   0xde688c8b857abeb4
+        .quad   0x3fc48e961c59326e
+        .quad   0x0b2e73ca15c9b8ba
+
+        // 2^236 * 7 * B
+
+        .quad   0xd6bb4428c17f5026
+        .quad   0x9eb27223fb5a9ca7
+        .quad   0xe37ba5031919c644
+        .quad   0x21ce380db59a6602
+        .quad   0x0e3fbfaf79c03a55
+        .quad   0x3077af054cbb5acf
+        .quad   0xd5c55245db3de39f
+        .quad   0x015e68c1476a4af7
+        .quad   0xc1d5285220066a38
+        .quad   0x95603e523570aef3
+        .quad   0x832659a7226b8a4d
+        .quad   0x5dd689091f8eedc9
+
+        // 2^236 * 8 * B
+
+        .quad   0xcbac84debfd3c856
+        .quad   0x1624c348b35ff244
+        .quad   0xb7f88dca5d9cad07
+        .quad   0x3b0e574da2c2ebe8
+        .quad   0x1d022591a5313084
+        .quad   0xca2d4aaed6270872
+        .quad   0x86a12b852f0bfd20
+        .quad   0x56e6c439ad7da748
+        .quad   0xc704ff4942bdbae6
+        .quad   0x5e21ade2b2de1f79
+        .quad   0xe95db3f35652fad8
+        .quad   0x0822b5378f08ebc1
+
+        // 2^240 * 1 * B
+
+        .quad   0x51f048478f387475
+        .quad   0xb25dbcf49cbecb3c
+        .quad   0x9aab1244d99f2055
+        .quad   0x2c709e6c1c10a5d6
+        .quad   0xe1b7f29362730383
+        .quad   0x4b5279ffebca8a2c
+        .quad   0xdafc778abfd41314
+        .quad   0x7deb10149c72610f
+        .quad   0xcb62af6a8766ee7a
+        .quad   0x66cbec045553cd0e
+        .quad   0x588001380f0be4b5
+        .quad   0x08e68e9ff62ce2ea
+
+        // 2^240 * 2 * B
+
+        .quad   0x34ad500a4bc130ad
+        .quad   0x8d38db493d0bd49c
+        .quad   0xa25c3d98500a89be
+        .quad   0x2f1f3f87eeba3b09
+        .quad   0x2f2d09d50ab8f2f9
+        .quad   0xacb9218dc55923df
+        .quad   0x4a8f342673766cb9
+        .quad   0x4cb13bd738f719f5
+        .quad   0xf7848c75e515b64a
+        .quad   0xa59501badb4a9038
+        .quad   0xc20d313f3f751b50
+        .quad   0x19a1e353c0ae2ee8
+
+        // 2^240 * 3 * B
+
+        .quad   0x7d1c7560bafa05c3
+        .quad   0xb3e1a0a0c6e55e61
+        .quad   0xe3529718c0d66473
+        .quad   0x41546b11c20c3486
+        .quad   0xb42172cdd596bdbd
+        .quad   0x93e0454398eefc40
+        .quad   0x9fb15347b44109b5
+        .quad   0x736bd3990266ae34
+        .quad   0x85532d509334b3b4
+        .quad   0x46fd114b60816573
+        .quad   0xcc5f5f30425c8375
+        .quad   0x412295a2b87fab5c
+
+        // 2^240 * 4 * B
+
+        .quad   0x19c99b88f57ed6e9
+        .quad   0x5393cb266df8c825
+        .quad   0x5cee3213b30ad273
+        .quad   0x14e153ebb52d2e34
+        .quad   0x2e655261e293eac6
+        .quad   0x845a92032133acdb
+        .quad   0x460975cb7900996b
+        .quad   0x0760bb8d195add80
+        .quad   0x413e1a17cde6818a
+        .quad   0x57156da9ed69a084
+        .quad   0x2cbf268f46caccb1
+        .quad   0x6b34be9bc33ac5f2
+
+        // 2^240 * 5 * B
+
+        .quad   0xf3df2f643a78c0b2
+        .quad   0x4c3e971ef22e027c
+        .quad   0xec7d1c5e49c1b5a3
+        .quad   0x2012c18f0922dd2d
+        .quad   0x11fc69656571f2d3
+        .quad   0xc6c9e845530e737a
+        .quad   0xe33ae7a2d4fe5035
+        .quad   0x01b9c7b62e6dd30b
+        .quad   0x880b55e55ac89d29
+        .quad   0x1483241f45a0a763
+        .quad   0x3d36efdfc2e76c1f
+        .quad   0x08af5b784e4bade8
+
+        // 2^240 * 6 * B
+
+        .quad   0x283499dc881f2533
+        .quad   0x9d0525da779323b6
+        .quad   0x897addfb673441f4
+        .quad   0x32b79d71163a168d
+        .quad   0xe27314d289cc2c4b
+        .quad   0x4be4bd11a287178d
+        .quad   0x18d528d6fa3364ce
+        .quad   0x6423c1d5afd9826e
+        .quad   0xcc85f8d9edfcb36a
+        .quad   0x22bcc28f3746e5f9
+        .quad   0xe49de338f9e5d3cd
+        .quad   0x480a5efbc13e2dcc
+
+        // 2^240 * 7 * B
+
+        .quad   0x0b51e70b01622071
+        .quad   0x06b505cf8b1dafc5
+        .quad   0x2c6bb061ef5aabcd
+        .quad   0x47aa27600cb7bf31
+        .quad   0xb6614ce442ce221f
+        .quad   0x6e199dcc4c053928
+        .quad   0x663fb4a4dc1cbe03
+        .quad   0x24b31d47691c8e06
+        .quad   0x2a541eedc015f8c3
+        .quad   0x11a4fe7e7c693f7c
+        .quad   0xf0af66134ea278d6
+        .quad   0x545b585d14dda094
+
+        // 2^240 * 8 * B
+
+        .quad   0x67bf275ea0d43a0f
+        .quad   0xade68e34089beebe
+        .quad   0x4289134cd479e72e
+        .quad   0x0f62f9c332ba5454
+        .quad   0x6204e4d0e3b321e1
+        .quad   0x3baa637a28ff1e95
+        .quad   0x0b0ccffd5b99bd9e
+        .quad   0x4d22dc3e64c8d071
+        .quad   0xfcb46589d63b5f39
+        .quad   0x5cae6a3f57cbcf61
+        .quad   0xfebac2d2953afa05
+        .quad   0x1c0fa01a36371436
+
+        // 2^244 * 1 * B
+
+        .quad   0xe7547449bc7cd692
+        .quad   0x0f9abeaae6f73ddf
+        .quad   0x4af01ca700837e29
+        .quad   0x63ab1b5d3f1bc183
+        .quad   0xc11ee5e854c53fae
+        .quad   0x6a0b06c12b4f3ff4
+        .quad   0x33540f80e0b67a72
+        .quad   0x15f18fc3cd07e3ef
+        .quad   0x32750763b028f48c
+        .quad   0x06020740556a065f
+        .quad   0xd53bd812c3495b58
+        .quad   0x08706c9b865f508d
+
+        // 2^244 * 2 * B
+
+        .quad   0xf37ca2ab3d343dff
+        .quad   0x1a8c6a2d80abc617
+        .quad   0x8e49e035d4ccffca
+        .quad   0x48b46beebaa1d1b9
+        .quad   0xcc991b4138b41246
+        .quad   0x243b9c526f9ac26b
+        .quad   0xb9ef494db7cbabbd
+        .quad   0x5fba433dd082ed00
+        .quad   0x9c49e355c9941ad0
+        .quad   0xb9734ade74498f84
+        .quad   0x41c3fed066663e5c
+        .quad   0x0ecfedf8e8e710b3
+
+        // 2^244 * 3 * B
+
+        .quad   0x76430f9f9cd470d9
+        .quad   0xb62acc9ba42f6008
+        .quad   0x1898297c59adad5e
+        .quad   0x7789dd2db78c5080
+        .quad   0x744f7463e9403762
+        .quad   0xf79a8dee8dfcc9c9
+        .quad   0x163a649655e4cde3
+        .quad   0x3b61788db284f435
+        .quad   0xb22228190d6ef6b2
+        .quad   0xa94a66b246ce4bfa
+        .quad   0x46c1a77a4f0b6cc7
+        .quad   0x4236ccffeb7338cf
+
+        // 2^244 * 4 * B
+
+        .quad   0x8497404d0d55e274
+        .quad   0x6c6663d9c4ad2b53
+        .quad   0xec2fb0d9ada95734
+        .quad   0x2617e120cdb8f73c
+        .quad   0x3bd82dbfda777df6
+        .quad   0x71b177cc0b98369e
+        .quad   0x1d0e8463850c3699
+        .quad   0x5a71945b48e2d1f1
+        .quad   0x6f203dd5405b4b42
+        .quad   0x327ec60410b24509
+        .quad   0x9c347230ac2a8846
+        .quad   0x77de29fc11ffeb6a
+
+        // 2^244 * 5 * B
+
+        .quad   0xb0ac57c983b778a8
+        .quad   0x53cdcca9d7fe912c
+        .quad   0x61c2b854ff1f59dc
+        .quad   0x3a1a2cf0f0de7dac
+        .quad   0x835e138fecced2ca
+        .quad   0x8c9eaf13ea963b9a
+        .quad   0xc95fbfc0b2160ea6
+        .quad   0x575e66f3ad877892
+        .quad   0x99803a27c88fcb3a
+        .quad   0x345a6789275ec0b0
+        .quad   0x459789d0ff6c2be5
+        .quad   0x62f882651e70a8b2
+
+        // 2^244 * 6 * B
+
+        .quad   0x085ae2c759ff1be4
+        .quad   0x149145c93b0e40b7
+        .quad   0xc467e7fa7ff27379
+        .quad   0x4eeecf0ad5c73a95
+        .quad   0x6d822986698a19e0
+        .quad   0xdc9821e174d78a71
+        .quad   0x41a85f31f6cb1f47
+        .quad   0x352721c2bcda9c51
+        .quad   0x48329952213fc985
+        .quad   0x1087cf0d368a1746
+        .quad   0x8e5261b166c15aa5
+        .quad   0x2d5b2d842ed24c21
+
+        // 2^244 * 7 * B
+
+        .quad   0x02cfebd9ebd3ded1
+        .quad   0xd45b217739021974
+        .quad   0x7576f813fe30a1b7
+        .quad   0x5691b6f9a34ef6c2
+        .quad   0x5eb7d13d196ac533
+        .quad   0x377234ecdb80be2b
+        .quad   0xe144cffc7cf5ae24
+        .quad   0x5226bcf9c441acec
+        .quad   0x79ee6c7223e5b547
+        .quad   0x6f5f50768330d679
+        .quad   0xed73e1e96d8adce9
+        .quad   0x27c3da1e1d8ccc03
+
+        // 2^244 * 8 * B
+
+        .quad   0x7eb9efb23fe24c74
+        .quad   0x3e50f49f1651be01
+        .quad   0x3ea732dc21858dea
+        .quad   0x17377bd75bb810f9
+        .quad   0x28302e71630ef9f6
+        .quad   0xc2d4a2032b64cee0
+        .quad   0x090820304b6292be
+        .quad   0x5fca747aa82adf18
+        .quad   0x232a03c35c258ea5
+        .quad   0x86f23a2c6bcb0cf1
+        .quad   0x3dad8d0d2e442166
+        .quad   0x04a8933cab76862b
+
+        // 2^248 * 1 * B
+
+        .quad   0xd2c604b622943dff
+        .quad   0xbc8cbece44cfb3a0
+        .quad   0x5d254ff397808678
+        .quad   0x0fa3614f3b1ca6bf
+        .quad   0x69082b0e8c936a50
+        .quad   0xf9c9a035c1dac5b6
+        .quad   0x6fb73e54c4dfb634
+        .quad   0x4005419b1d2bc140
+        .quad   0xa003febdb9be82f0
+        .quad   0x2089c1af3a44ac90
+        .quad   0xf8499f911954fa8e
+        .quad   0x1fba218aef40ab42
+
+        // 2^248 * 2 * B
+
+        .quad   0xab549448fac8f53e
+        .quad   0x81f6e89a7ba63741
+        .quad   0x74fd6c7d6c2b5e01
+        .quad   0x392e3acaa8c86e42
+        .quad   0x4f3e57043e7b0194
+        .quad   0xa81d3eee08daaf7f
+        .quad   0xc839c6ab99dcdef1
+        .quad   0x6c535d13ff7761d5
+        .quad   0x4cbd34e93e8a35af
+        .quad   0x2e0781445887e816
+        .quad   0x19319c76f29ab0ab
+        .quad   0x25e17fe4d50ac13b
+
+        // 2^248 * 3 * B
+
+        .quad   0x0a289bd71e04f676
+        .quad   0x208e1c52d6420f95
+        .quad   0x5186d8b034691fab
+        .quad   0x255751442a9fb351
+        .quad   0x915f7ff576f121a7
+        .quad   0xc34a32272fcd87e3
+        .quad   0xccba2fde4d1be526
+        .quad   0x6bba828f8969899b
+        .quad   0xe2d1bc6690fe3901
+        .quad   0x4cb54a18a0997ad5
+        .quad   0x971d6914af8460d4
+        .quad   0x559d504f7f6b7be4
+
+        // 2^248 * 4 * B
+
+        .quad   0xa7738378b3eb54d5
+        .quad   0x1d69d366a5553c7c
+        .quad   0x0a26cf62f92800ba
+        .quad   0x01ab12d5807e3217
+        .quad   0x9c4891e7f6d266fd
+        .quad   0x0744a19b0307781b
+        .quad   0x88388f1d6061e23b
+        .quad   0x123ea6a3354bd50e
+        .quad   0x118d189041e32d96
+        .quad   0xb9ede3c2d8315848
+        .quad   0x1eab4271d83245d9
+        .quad   0x4a3961e2c918a154
+
+        // 2^248 * 5 * B
+
+        .quad   0x71dc3be0f8e6bba0
+        .quad   0xd6cef8347effe30a
+        .quad   0xa992425fe13a476a
+        .quad   0x2cd6bce3fb1db763
+        .quad   0x0327d644f3233f1e
+        .quad   0x499a260e34fcf016
+        .quad   0x83b5a716f2dab979
+        .quad   0x68aceead9bd4111f
+        .quad   0x38b4c90ef3d7c210
+        .quad   0x308e6e24b7ad040c
+        .quad   0x3860d9f1b7e73e23
+        .quad   0x595760d5b508f597
+
+        // 2^248 * 6 * B
+
+        .quad   0x6129bfe104aa6397
+        .quad   0x8f960008a4a7fccb
+        .quad   0x3f8bc0897d909458
+        .quad   0x709fa43edcb291a9
+        .quad   0x882acbebfd022790
+        .quad   0x89af3305c4115760
+        .quad   0x65f492e37d3473f4
+        .quad   0x2cb2c5df54515a2b
+        .quad   0xeb0a5d8c63fd2aca
+        .quad   0xd22bc1662e694eff
+        .quad   0x2723f36ef8cbb03a
+        .quad   0x70f029ecf0c8131f
+
+        // 2^248 * 7 * B
+
+        .quad   0x461307b32eed3e33
+        .quad   0xae042f33a45581e7
+        .quad   0xc94449d3195f0366
+        .quad   0x0b7d5d8a6c314858
+        .quad   0x2a6aafaa5e10b0b9
+        .quad   0x78f0a370ef041aa9
+        .quad   0x773efb77aa3ad61f
+        .quad   0x44eca5a2a74bd9e1
+        .quad   0x25d448327b95d543
+        .quad   0x70d38300a3340f1d
+        .quad   0xde1c531c60e1c52b
+        .quad   0x272224512c7de9e4
+
+        // 2^248 * 8 * B
+
+        .quad   0x1abc92af49c5342e
+        .quad   0xffeed811b2e6fad0
+        .quad   0xefa28c8dfcc84e29
+        .quad   0x11b5df18a44cc543
+        .quad   0xbf7bbb8a42a975fc
+        .quad   0x8c5c397796ada358
+        .quad   0xe27fc76fcdedaa48
+        .quad   0x19735fd7f6bc20a6
+        .quad   0xe3ab90d042c84266
+        .quad   0xeb848e0f7f19547e
+        .quad   0x2503a1d065a497b9
+        .quad   0x0fef911191df895f
diff --git a/cbits/s2n/arm/edwards25519_scalarmulbase_alt.S b/cbits/s2n/arm/edwards25519_scalarmulbase_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/edwards25519_scalarmulbase_alt.S
@@ -0,0 +1,9477 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Scalar multiplication for the edwards25519 standard basepoint
+// Input scalar[4]; output res[8]
+//
+// extern void edwards25519_scalarmulbase_alt
+//   (uint64_t res[static 8],const uint64_t scalar[static 4]);
+//
+// Given a scalar n, returns point (X,Y) = n * B where B = (...,4/5) is
+// the standard basepoint for the edwards25519 (Ed25519) curve.
+//
+// Standard ARM ABI: X0 = res, X1 = scalar
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_scalarmulbase_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_scalarmulbase_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_scalarmulbase_alt)
+
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable home for the input result argument during the whole body
+
+#define res x23
+
+// Other variables that are only needed prior to the modular inverse.
+
+#define tab x19
+
+#define i x20
+
+#define bias x21
+
+#define bf x22
+#define ix x22
+
+// Pointer-offset pairs for result and temporaries on stack with some aliasing.
+
+#define resx res, #(0*NUMSIZE)
+#define resy res, #(1*NUMSIZE)
+
+#define scalar sp, #(0*NUMSIZE)
+
+#define tabent sp, #(1*NUMSIZE)
+#define ymx_2 sp, #(1*NUMSIZE)
+#define xpy_2 sp, #(2*NUMSIZE)
+#define kxy_2 sp, #(3*NUMSIZE)
+
+#define acc sp, #(4*NUMSIZE)
+#define x_1 sp, #(4*NUMSIZE)
+#define y_1 sp, #(5*NUMSIZE)
+#define z_1 sp, #(6*NUMSIZE)
+#define w_1 sp, #(7*NUMSIZE)
+#define x_3 sp, #(4*NUMSIZE)
+#define y_3 sp, #(5*NUMSIZE)
+#define z_3 sp, #(6*NUMSIZE)
+#define w_3 sp, #(7*NUMSIZE)
+
+#define tmpspace sp, #(8*NUMSIZE)
+#define t0 sp, #(8*NUMSIZE)
+#define t1 sp, #(9*NUMSIZE)
+#define t2 sp, #(10*NUMSIZE)
+#define t3 sp, #(11*NUMSIZE)
+#define t4 sp, #(12*NUMSIZE)
+#define t5 sp, #(13*NUMSIZE)
+
+// Total size to reserve on the stack
+
+#define NSPACE 14*NUMSIZE
+
+// Load 64-bit immediate into a register
+
+#define movbig(nn,n3,n2,n1,n0)                                      \
+        movz    nn, n0 __LF                                            \
+        movk    nn, n1, lsl #16 __LF                                   \
+        movk    nn, n2, lsl #32 __LF                                   \
+        movk    nn, n3, lsl #48
+
+// Macro wrapping up the basic field operation bignum_mul_p25519_alt, only
+// trivially different from a pure function call to that subroutine.
+
+#define mul_p25519(P0,P1,P2)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        mul     x12, x3, x7 __LF                   \
+        umulh   x13, x3, x7 __LF                   \
+        mul     x11, x3, x8 __LF                   \
+        umulh   x14, x3, x8 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x9 __LF                   \
+        umulh   x15, x3, x9 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x3, x10 __LF                  \
+        umulh   x16, x3, x10 __LF                  \
+        adcs    x15, x15, x11 __LF                 \
+        adc     x16, x16, xzr __LF                 \
+        ldp     x5, x6, [P1+16] __LF               \
+        mul     x11, x4, x7 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        mul     x11, x4, x8 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x4, x9 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        mul     x11, x4, x10 __LF                  \
+        adcs    x16, x16, x11 __LF                 \
+        umulh   x3, x4, x10 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        umulh   x11, x4, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        umulh   x11, x4, x8 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        umulh   x11, x4, x9 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        adc     x3, x3, xzr __LF                   \
+        mul     x11, x5, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        mul     x11, x5, x8 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        mul     x11, x5, x9 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        mul     x11, x5, x10 __LF                  \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x4, x5, x10 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        umulh   x11, x5, x7 __LF                   \
+        adds    x15, x15, x11 __LF                 \
+        umulh   x11, x5, x8 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        umulh   x11, x5, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        mul     x11, x6, x7 __LF                   \
+        adds    x15, x15, x11 __LF                 \
+        mul     x11, x6, x8 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        mul     x11, x6, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        mul     x11, x6, x10 __LF                  \
+        adcs    x4, x4, x11 __LF                   \
+        umulh   x5, x6, x10 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        umulh   x11, x6, x7 __LF                   \
+        adds    x16, x16, x11 __LF                 \
+        umulh   x11, x6, x8 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x11, x6, x9 __LF                   \
+        adcs    x4, x4, x11 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        mov     x7, #0x26 __LF                     \
+        mul     x11, x7, x16 __LF                  \
+        umulh   x9, x7, x16 __LF                   \
+        adds    x12, x12, x11 __LF                 \
+        mul     x11, x7, x3 __LF                   \
+        umulh   x3, x7, x3 __LF                    \
+        adcs    x13, x13, x11 __LF                 \
+        mul     x11, x7, x4 __LF                   \
+        umulh   x4, x7, x4 __LF                    \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x7, x5 __LF                   \
+        umulh   x5, x7, x5 __LF                    \
+        adcs    x15, x15, x11 __LF                 \
+        cset    x16, cs __LF                       \
+        adds    x15, x15, x4 __LF                  \
+        adc     x16, x16, x5 __LF                  \
+        cmn     x15, x15 __LF                      \
+        orr     x15, x15, #0x8000000000000000 __LF \
+        adc     x8, x16, x16 __LF                  \
+        mov     x7, #0x13 __LF                     \
+        madd    x11, x7, x8, x7 __LF               \
+        adds    x12, x12, x11 __LF                 \
+        adcs    x13, x13, x9 __LF                  \
+        adcs    x14, x14, x3 __LF                  \
+        adcs    x15, x15, xzr __LF                 \
+        csel    x7, x7, xzr, cc __LF               \
+        subs    x12, x12, x7 __LF                  \
+        sbcs    x13, x13, xzr __LF                 \
+        sbcs    x14, x14, xzr __LF                 \
+        sbc     x15, x15, xzr __LF                 \
+        and     x15, x15, #0x7fffffffffffffff __LF \
+        stp     x12, x13, [P0] __LF                \
+        stp     x14, x15, [P0+16]
+
+// A version of multiplication that only guarantees output < 2 * p_25519.
+// This basically skips the +1 and final correction in quotient estimation.
+
+#define mul_4(P0,P1,P2)                         \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        mul     x12, x3, x7 __LF                   \
+        umulh   x13, x3, x7 __LF                   \
+        mul     x11, x3, x8 __LF                   \
+        umulh   x14, x3, x8 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x9 __LF                   \
+        umulh   x15, x3, x9 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x3, x10 __LF                  \
+        umulh   x16, x3, x10 __LF                  \
+        adcs    x15, x15, x11 __LF                 \
+        adc     x16, x16, xzr __LF                 \
+        ldp     x5, x6, [P1+16] __LF               \
+        mul     x11, x4, x7 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        mul     x11, x4, x8 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x4, x9 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        mul     x11, x4, x10 __LF                  \
+        adcs    x16, x16, x11 __LF                 \
+        umulh   x3, x4, x10 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        umulh   x11, x4, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        umulh   x11, x4, x8 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        umulh   x11, x4, x9 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        adc     x3, x3, xzr __LF                   \
+        mul     x11, x5, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        mul     x11, x5, x8 __LF                   \
+        adcs    x15, x15, x11 __LF                 \
+        mul     x11, x5, x9 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        mul     x11, x5, x10 __LF                  \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x4, x5, x10 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        umulh   x11, x5, x7 __LF                   \
+        adds    x15, x15, x11 __LF                 \
+        umulh   x11, x5, x8 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        umulh   x11, x5, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        mul     x11, x6, x7 __LF                   \
+        adds    x15, x15, x11 __LF                 \
+        mul     x11, x6, x8 __LF                   \
+        adcs    x16, x16, x11 __LF                 \
+        mul     x11, x6, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        mul     x11, x6, x10 __LF                  \
+        adcs    x4, x4, x11 __LF                   \
+        umulh   x5, x6, x10 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        umulh   x11, x6, x7 __LF                   \
+        adds    x16, x16, x11 __LF                 \
+        umulh   x11, x6, x8 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x11, x6, x9 __LF                   \
+        adcs    x4, x4, x11 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        mov     x7, #0x26 __LF                     \
+        mul     x11, x7, x16 __LF                  \
+        umulh   x9, x7, x16 __LF                   \
+        adds    x12, x12, x11 __LF                 \
+        mul     x11, x7, x3 __LF                   \
+        umulh   x3, x7, x3 __LF                    \
+        adcs    x13, x13, x11 __LF                 \
+        mul     x11, x7, x4 __LF                   \
+        umulh   x4, x7, x4 __LF                    \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x7, x5 __LF                   \
+        umulh   x5, x7, x5 __LF                    \
+        adcs    x15, x15, x11 __LF                 \
+        cset    x16, cs __LF                       \
+        adds    x15, x15, x4 __LF                  \
+        adc     x16, x16, x5 __LF                  \
+        cmn     x15, x15 __LF                      \
+        bic     x15, x15, #0x8000000000000000 __LF \
+        adc     x8, x16, x16 __LF                  \
+        mov     x7, #0x13 __LF                     \
+        mul     x11, x7, x8 __LF                   \
+        adds    x12, x12, x11 __LF                 \
+        adcs    x13, x13, x9 __LF                  \
+        adcs    x14, x14, x3 __LF                  \
+        adc     x15, x15, xzr __LF                 \
+        stp     x12, x13, [P0] __LF                \
+        stp     x14, x15, [P0+16]
+
+// Modular subtraction with double modulus 2 * p_25519 = 2^256 - 38
+
+#define sub_twice4(P0,P1,P2)                    \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        mov     x4, #38 __LF                       \
+        csel    x3, x4, xzr, lo __LF               \
+        subs    x5, x5, x3 __LF                    \
+        sbcs    x6, x6, xzr __LF                   \
+        sbcs    x7, x7, xzr __LF                   \
+        sbc     x8, x8, xzr __LF                   \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+// Modular addition and doubling with double modulus 2 * p_25519 = 2^256 - 38.
+// This only ensures that the result fits in 4 digits, not that it is reduced
+// even w.r.t. double modulus. The result is always correct modulo provided
+// the sum of the inputs is < 2^256 + 2^256 - 38, so in particular provided
+// at least one of them is reduced double modulo.
+
+#define add_twice4(P0,P1,P2)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        adds    x3, x3, x7 __LF                    \
+        adcs    x4, x4, x8 __LF                    \
+        ldp     x5, x6, [P1+16] __LF               \
+        ldp     x7, x8, [P2+16] __LF               \
+        adcs    x5, x5, x7 __LF                    \
+        adcs    x6, x6, x8 __LF                    \
+        mov     x9, #38 __LF                       \
+        csel    x9, x9, xzr, cs __LF               \
+        adds    x3, x3, x9 __LF                    \
+        adcs    x4, x4, xzr __LF                   \
+        adcs    x5, x5, xzr __LF                   \
+        adc     x6, x6, xzr __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+#define double_twice4(P0,P1)                    \
+        ldp     x3, x4, [P1] __LF                  \
+        adds    x3, x3, x3 __LF                    \
+        adcs    x4, x4, x4 __LF                    \
+        ldp     x5, x6, [P1+16] __LF               \
+        adcs    x5, x5, x5 __LF                    \
+        adcs    x6, x6, x6 __LF                    \
+        mov     x9, #38 __LF                       \
+        csel    x9, x9, xzr, cs __LF               \
+        adds    x3, x3, x9 __LF                    \
+        adcs    x4, x4, xzr __LF                   \
+        adcs    x5, x5, xzr __LF                   \
+        adc     x6, x6, xzr __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt):
+        CFI_START
+
+// Save regs and make room for temporaries
+
+        CFI_PUSH2(x19,x20)
+        CFI_PUSH2(x21,x22)
+        CFI_PUSH2(x23,x24)
+        CFI_DEC_SP(NSPACE)
+
+// Move the output pointer to a stable place
+
+        mov     res, x0
+
+// Copy the input scalar x to its local variable while reducing it
+// modulo 2^252 + m where m = 27742317777372353535851937790883648493;
+// this is the order of the basepoint so this doesn't change the result.
+// First do q = floor(x/2^252) and x' = x - q * (2^252 + m), which gives
+// an initial result -15 * m <= x' < 2^252
+
+        ldp     x10, x11, [x1]
+        ldp     x12, x13, [x1, #16]
+
+        lsr     x9, x13, #60
+
+        movbig(x0,#0x5812,#0x631a,#0x5cf5,#0xd3ed);
+        movbig(x1,#0x14de,#0xf9de,#0xa2f7,#0x9cd6);
+
+        mul     x2, x9, x0
+        mul     x3, x9, x1
+        umulh   x4, x9, x0
+        umulh   x5, x9, x1
+
+        adds    x3, x3, x4
+        adc     x4, x5, xzr
+        lsl     x5, x9, #60
+
+        subs    x10, x10, x2
+        sbcs    x11, x11, x3
+        sbcs    x12, x12, x4
+        sbcs    x13, x13, x5
+
+// If x' < 0 then just directly negate it; this makes sure the
+// reduced argument is strictly 0 <= x' < 2^252, but now we need
+// to record (done via bit 255 of the reduced scalar, which is
+// ignored in the main loop) when we negated so we can flip
+// the sign of the eventual point to compensate.
+
+        csetm   x9, cc
+        adds    xzr, x9, x9
+        eor     x10, x10, x9
+        adcs    x10, x10, xzr
+        eor     x11, x11, x9
+        adcs    x11, x11, xzr
+        eor     x12, x12, x9
+        adcs    x12, x12, xzr
+        eor     x13, x13, x9
+        adc     x13, x13, xzr
+
+        and     x9, x9, #0x8000000000000000
+        orr     x13, x13, x9
+
+// And before we store the scalar, test and reset bit 251 to
+// initialize the main loop just below.
+
+        stp     x10, x11, [scalar]
+        tst     x13, #0x0800000000000000
+        bic     x13, x13, #0x0800000000000000
+        stp     x12, x13, [scalar+16]
+
+// The main part of the computation is in extended-projective coordinates
+// (X,Y,Z,T), representing an affine point on the edwards25519 curve
+// (x,y) via x = X/Z, y = Y/Z and x * y = T/Z (so X * Y = T * Z).
+// In comments B means the standard basepoint (x,4/5) =
+// (0x216....f25d51a,0x6666..666658).
+//
+// Initialize accumulator "acc" to either 0 or 2^251 * B depending on
+// bit 251 of the (reduced) scalar. That leaves bits 0..250 to handle.
+
+#if defined(__ELF__)
+        adrp    tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant)
+        add     tab, tab, :lo12:S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant)
+#else
+        adrp    tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant)@PAGE
+        add     tab, tab, S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant)@PAGEOFF
+#endif
+
+        ldp     x0, x1, [tab]
+        ldp     x2, x3, [tab, #96]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc]
+
+        ldp     x0, x1, [tab, #1*16]
+        ldp     x2, x3, [tab, #(96+1*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+1*16]
+
+        ldp     x0, x1, [tab, #2*16]
+        ldp     x2, x3, [tab, #(96+2*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+2*16]
+
+        ldp     x0, x1, [tab, #3*16]
+        ldp     x2, x3, [tab, #(96+3*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+3*16]
+
+        mov     x0, #1
+        stp     x0, xzr, [acc+4*16]
+        stp     xzr, xzr, [acc+5*16]
+
+        ldp     x0, x1, [tab, #4*16]
+        ldp     x2, x3, [tab, #(96+4*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+6*16]
+
+        ldp     x0, x1, [tab, #5*16]
+        ldp     x2, x3, [tab, #(96+5*16)]
+        csel    x0, x0, x2, eq
+        csel    x1, x1, x3, eq
+        stp     x0, x1, [acc+7*16]
+
+// The counter "i" tracks the bit position for which the scalar has
+// already been absorbed, starting at 0 and going up in chunks of 4.
+//
+// The pointer "tab" points at the current block of the table for
+// multiples (2^i * j) * B at the current bit position i; 1 <= j <= 8.
+//
+// The bias is always either 0 and 1 and needs to be added to the
+// partially processed scalar implicitly. This is used to absorb 4 bits
+// of scalar per iteration from 3-bit table indexing by exploiting
+// negation: (16 * h + l) * B = (16 * (h + 1) - (16 - l)) * B is used
+// when l >= 9. Note that we can't have any bias left over at the
+// end because we made sure bit 251 is clear in the reduced scalar.
+
+        mov     i, 0
+        add     tab, tab, #192
+        mov     bias, xzr
+
+// Start of the main loop, repeated 63 times for i = 0, 4, 8, ..., 248
+
+Ledwards25519_scalarmulbase_alt_scalarloop:
+
+// Look at the next 4-bit field "bf", adding the previous bias as well.
+// Choose the table index "ix" as bf when bf <= 8 and 16 - bf for bf >= 9,
+// setting the bias to 1 for the next iteration in the latter case.
+
+        lsr     x0, i, #6
+        ldr     x2, [sp, x0, lsl #3]    // Exploiting scalar = sp exactly
+        lsr     x2, x2, i
+        and     x2, x2, #15
+        add     bf, x2, bias
+
+        cmp     bf, 9
+        cset    bias, cs
+
+        mov     x0, 16
+        sub     x0, x0, bf
+        cmp     bias, xzr
+        csel    ix, x0, bf, ne
+
+// Perform constant-time lookup in the table to get element number "ix".
+// The table entry for the affine point (x,y) is actually a triple
+// (y - x,x + y,2 * d * x * y) to precompute parts of the addition.
+// Note that "ix" can be 0, so we set up the appropriate identity first.
+
+        mov     x0, #1
+        mov     x1, xzr
+        mov     x2, xzr
+        mov     x3, xzr
+        mov     x4, #1
+        mov     x5, xzr
+        mov     x6, xzr
+        mov     x7, xzr
+        mov     x8, xzr
+        mov     x9, xzr
+        mov     x10, xzr
+        mov     x11, xzr
+
+        cmp     ix, #1
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #2
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #3
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #4
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #5
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #6
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #7
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+        cmp     ix, #8
+        ldp     x12, x13, [tab]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x12, x13, [tab, #16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+        ldp     x12, x13, [tab, #32]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x12, x13, [tab, #48]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+        ldp     x12, x13, [tab, #64]
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x12, x13, [tab, #80]
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+        add     tab, tab, #96
+
+// We now have the triple from the table in registers as follows
+//
+//      [x3;x2;x1;x0] = y - x
+//      [x7;x6;x5;x4] = x + y
+//      [x11;x10;x9;x8] = 2 * d * x * y
+//
+// In case bias = 1 we need to negate this. For Edwards curves
+// -(x,y) = (-x,y), i.e. we need to negate the x coordinate.
+// In this processed encoding, that amounts to swapping the
+// first two fields and negating the third.
+//
+// The optional negation here also pretends bias = 0 whenever
+// ix = 0 so that it doesn't need to handle the case of zero
+// inputs, since no non-trivial table entries are zero. Note
+// that in the zero case the whole negation is trivial, and
+// so indeed is the swapping.
+
+        cmp     bias, #0
+
+        csel    x12, x0, x4, eq
+        csel    x13, x1, x5, eq
+        csel    x14, x2, x6, eq
+        csel    x15, x3, x7, eq
+        stp     x12, x13, [tabent]
+        stp     x14, x15, [tabent+16]
+
+        csel    x12, x0, x4, ne
+        csel    x13, x1, x5, ne
+        csel    x14, x2, x6, ne
+        csel    x15, x3, x7, ne
+        stp     x12, x13, [tabent+32]
+        stp     x14, x15, [tabent+48]
+
+        mov     x0, #-19
+        subs    x0, x0, x8
+        mov     x2, #-1
+        sbcs    x1, x2, x9
+        sbcs    x2, x2, x10
+        mov     x3, #0x7FFFFFFFFFFFFFFF
+        sbc     x3, x3, x11
+
+        cmp     ix, xzr
+        ccmp    bias, xzr, #4, ne
+
+        csel    x0, x0, x8, ne
+        csel    x1, x1, x9, ne
+        stp     x0, x1, [tabent+64]
+        csel    x2, x2, x10, ne
+        csel    x3, x3, x11, ne
+        stp     x2, x3, [tabent+80]
+
+// Extended-projective and precomputed mixed addition.
+// This is effectively the same as calling the standalone
+// function edwards25519_pepadd_alt(acc,acc,tabent), but we
+// only retain slightly weaker normalization < 2 * p_25519
+// throughout the inner loop, so the computation is
+// slightly different, and faster overall.
+
+        double_twice4(t0,z_1)
+        sub_twice4(t1,y_1,x_1)
+        add_twice4(t2,y_1,x_1)
+        mul_4(t3,w_1,kxy_2)
+        mul_4(t1,t1,ymx_2)
+        mul_4(t2,t2,xpy_2)
+        sub_twice4(t4,t0,t3)
+        add_twice4(t0,t0,t3)
+        sub_twice4(t5,t2,t1)
+        add_twice4(t1,t2,t1)
+        mul_4(z_3,t4,t0)
+        mul_4(x_3,t5,t4)
+        mul_4(y_3,t0,t1)
+        mul_4(w_3,t5,t1)
+
+// End of the main loop; move on by 4 bits.
+
+        add     i, i, 4
+        cmp     i, 252
+        bcc     Ledwards25519_scalarmulbase_alt_scalarloop
+
+// Insert the optional negation of the projective X coordinate, and
+// so by extension the final affine x coordinate x = X/Z and thus
+// the point P = (x,y). We only know X < 2 * p_25519, so we do the
+// negation as 2 * p_25519 - X to keep it nonnegative. From this
+// point on we don't need any normalization of the coordinates
+// except for making sure that they fit in 4 digits.
+
+        ldp     x0, x1, [x_3]
+        ldp     x2, x3, [x_3+16]
+        mov     x4, #0xffffffffffffffda
+        subs    x4, x4, x0
+        mov     x7, #0xffffffffffffffff
+        sbcs    x5, x7, x1
+        sbcs    x6, x7, x2
+        sbc     x7, x7, x3
+        ldr     x10, [scalar+24]
+        tst     x10, #0x8000000000000000
+        csel    x0, x4, x0, ne
+        csel    x1, x5, x1, ne
+        csel    x2, x6, x2, ne
+        csel    x3, x7, x3, ne
+        stp     x0, x1, [x_3]
+        stp     x2, x3, [x_3+16]
+
+// Now we need to map out of the extended-projective representation
+// (X,Y,Z,W) back to the affine form (x,y) = (X/Z,Y/Z). This means
+// first calling the modular inverse to get w_3 = 1/z_3.
+
+        add     x0, w_3
+        add     x1, z_3
+
+// Inline copy of bignum_inv_p25519, identical except for stripping out
+// the prologue and epilogue saving and restoring registers and making
+// and reclaiming room on the stack. For more details and explanations see
+// "arm/curve25519/bignum_inv_p25519.S". Note that the stack it uses for
+// its own temporaries is 128 bytes, so it has no effect on variables
+// that are needed in the rest of our computation here: res, w_3, x_3
+// and y_3.
+
+        mov     x20, x0
+        mov     x10, #0xffffffffffffffed
+        mov     x11, #0xffffffffffffffff
+        stp     x10, x11, [sp]
+        mov     x12, #0x7fffffffffffffff
+        stp     x11, x12, [sp, #16]
+        ldp     x2, x3, [x1]
+        ldp     x4, x5, [x1, #16]
+        mov     x7, #0x13
+        lsr     x6, x5, #63
+        madd    x6, x7, x6, x7
+        adds    x2, x2, x6
+        adcs    x3, x3, xzr
+        adcs    x4, x4, xzr
+        orr     x5, x5, #0x8000000000000000
+        adcs    x5, x5, xzr
+        csel    x6, x7, xzr, cc
+        subs    x2, x2, x6
+        sbcs    x3, x3, xzr
+        sbcs    x4, x4, xzr
+        sbc     x5, x5, xzr
+        and     x5, x5, #0x7fffffffffffffff
+        stp     x2, x3, [sp, #32]
+        stp     x4, x5, [sp, #48]
+        stp     xzr, xzr, [sp, #64]
+        stp     xzr, xzr, [sp, #80]
+        mov     x10, #0x2099
+        movk    x10, #0x7502, lsl #16
+        movk    x10, #0x9e23, lsl #32
+        movk    x10, #0xa0f9, lsl #48
+        mov     x11, #0x2595
+        movk    x11, #0x1d13, lsl #16
+        movk    x11, #0x8f3f, lsl #32
+        movk    x11, #0xa8c6, lsl #48
+        mov     x12, #0x5242
+        movk    x12, #0x5ac, lsl #16
+        movk    x12, #0x8938, lsl #32
+        movk    x12, #0x6c6c, lsl #48
+        mov     x13, #0x615
+        movk    x13, #0x4177, lsl #16
+        movk    x13, #0x8b2, lsl #32
+        movk    x13, #0x2765, lsl #48
+        stp     x10, x11, [sp, #96]
+        stp     x12, x13, [sp, #112]
+        mov     x21, #0xa
+        mov     x22, #0x1
+        b       Ledwards25519_scalarmulbase_alt_invmidloop
+Ledwards25519_scalarmulbase_alt_invloop:
+        cmp     x10, xzr
+        csetm   x14, mi
+        cneg    x10, x10, mi
+        cmp     x11, xzr
+        csetm   x15, mi
+        cneg    x11, x11, mi
+        cmp     x12, xzr
+        csetm   x16, mi
+        cneg    x12, x12, mi
+        cmp     x13, xzr
+        csetm   x17, mi
+        cneg    x13, x13, mi
+        and     x0, x10, x14
+        and     x1, x11, x15
+        add     x9, x0, x1
+        and     x0, x12, x16
+        and     x1, x13, x17
+        add     x19, x0, x1
+        ldr     x7, [sp]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #32]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        adc     x2, x2, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x5, x19, x0
+        adc     x3, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x7, [sp, #8]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #40]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        adc     x6, x6, x1
+        extr    x4, x2, x4, #59
+        str     x4, [sp]
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x3, x3, x0
+        adc     x4, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x3, x3, x0
+        adc     x4, x4, x1
+        extr    x5, x3, x5, #59
+        str     x5, [sp, #32]
+        ldr     x7, [sp, #16]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #48]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        adc     x5, x5, x1
+        extr    x2, x6, x2, #59
+        str     x2, [sp, #8]
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x4, x4, x0
+        adc     x2, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x4, x4, x0
+        adc     x2, x2, x1
+        extr    x3, x4, x3, #59
+        str     x3, [sp, #40]
+        ldr     x7, [sp, #24]
+        eor     x1, x7, x14
+        asr     x3, x1, #63
+        and     x3, x3, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #56]
+        eor     x1, x8, x15
+        asr     x0, x1, #63
+        and     x0, x0, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x5, x6, #59
+        str     x6, [sp, #16]
+        extr    x5, x3, x5, #59
+        str     x5, [sp, #24]
+        eor     x1, x7, x16
+        asr     x5, x1, #63
+        and     x5, x5, x12
+        neg     x5, x5
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        eor     x1, x8, x17
+        asr     x0, x1, #63
+        and     x0, x0, x13
+        sub     x5, x5, x0
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        extr    x4, x2, x4, #59
+        str     x4, [sp, #48]
+        extr    x2, x5, x2, #59
+        str     x2, [sp, #56]
+        ldr     x7, [sp, #64]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #96]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        str     x4, [sp, #64]
+        adc     x2, x2, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x5, x19, x0
+        adc     x3, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x5, x5, x0
+        str     x5, [sp, #96]
+        adc     x3, x3, x1
+        ldr     x7, [sp, #72]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #104]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        str     x2, [sp, #72]
+        adc     x6, x6, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x3, x3, x0
+        adc     x4, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x3, x3, x0
+        str     x3, [sp, #104]
+        adc     x4, x4, x1
+        ldr     x7, [sp, #80]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #112]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        str     x6, [sp, #80]
+        adc     x5, x5, x1
+        eor     x1, x7, x16
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x4, x4, x0
+        adc     x2, xzr, x1
+        eor     x1, x8, x17
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x4, x4, x0
+        str     x4, [sp, #112]
+        adc     x2, x2, x1
+        ldr     x7, [sp, #88]
+        eor     x1, x7, x14
+        and     x3, x14, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #120]
+        eor     x1, x8, x15
+        and     x0, x15, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x3, x5, #63
+        ldp     x0, x1, [sp, #64]
+        add     x6, x6, x3, asr #63
+        mov     x3, #0x13
+        mul     x4, x6, x3
+        add     x5, x5, x6, lsl #63
+        smulh   x3, x6, x3
+        ldr     x6, [sp, #80]
+        adds    x0, x0, x4
+        adcs    x1, x1, x3
+        asr     x3, x3, #63
+        adcs    x6, x6, x3
+        adc     x5, x5, x3
+        stp     x0, x1, [sp, #64]
+        stp     x6, x5, [sp, #80]
+        eor     x1, x7, x16
+        and     x5, x16, x12
+        neg     x5, x5
+        mul     x0, x1, x12
+        umulh   x1, x1, x12
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        eor     x1, x8, x17
+        and     x0, x17, x13
+        sub     x5, x5, x0
+        mul     x0, x1, x13
+        umulh   x1, x1, x13
+        adds    x2, x2, x0
+        adc     x5, x5, x1
+        extr    x6, x5, x2, #63
+        ldp     x0, x1, [sp, #96]
+        add     x6, x6, x5, asr #63
+        mov     x5, #0x13
+        mul     x4, x6, x5
+        add     x2, x2, x6, lsl #63
+        smulh   x5, x6, x5
+        ldr     x3, [sp, #112]
+        adds    x0, x0, x4
+        adcs    x1, x1, x5
+        asr     x5, x5, #63
+        adcs    x3, x3, x5
+        adc     x2, x2, x5
+        stp     x0, x1, [sp, #96]
+        stp     x3, x2, [sp, #112]
+Ledwards25519_scalarmulbase_alt_invmidloop:
+        mov     x1, x22
+        ldr     x2, [sp]
+        ldr     x3, [sp, #32]
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x8, x4, #0x100, lsl #12
+        sbfx    x8, x8, #21, #21
+        mov     x11, #0x100000
+        add     x11, x11, x11, lsl #21
+        add     x9, x4, x11
+        asr     x9, x9, #42
+        add     x10, x5, #0x100, lsl #12
+        sbfx    x10, x10, #21, #21
+        add     x11, x5, x11
+        asr     x11, x11, #42
+        mul     x6, x8, x2
+        mul     x7, x9, x3
+        mul     x2, x10, x2
+        mul     x3, x11, x3
+        add     x4, x6, x7
+        add     x5, x2, x3
+        asr     x2, x4, #20
+        asr     x3, x5, #20
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x12, x4, #0x100, lsl #12
+        sbfx    x12, x12, #21, #21
+        mov     x15, #0x100000
+        add     x15, x15, x15, lsl #21
+        add     x13, x4, x15
+        asr     x13, x13, #42
+        add     x14, x5, #0x100, lsl #12
+        sbfx    x14, x14, #21, #21
+        add     x15, x5, x15
+        asr     x15, x15, #42
+        mul     x6, x12, x2
+        mul     x7, x13, x3
+        mul     x2, x14, x2
+        mul     x3, x15, x3
+        add     x4, x6, x7
+        add     x5, x2, x3
+        asr     x2, x4, #20
+        asr     x3, x5, #20
+        and     x4, x2, #0xfffff
+        orr     x4, x4, #0xfffffe0000000000
+        and     x5, x3, #0xfffff
+        orr     x5, x5, #0xc000000000000000
+        tst     x5, #0x1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        mul     x2, x12, x8
+        mul     x3, x12, x9
+        mul     x6, x14, x8
+        mul     x7, x14, x9
+        madd    x8, x13, x10, x2
+        madd    x9, x13, x11, x3
+        madd    x16, x15, x10, x6
+        madd    x17, x15, x11, x7
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        tst     x5, #0x2
+        asr     x5, x5, #1
+        csel    x6, x4, xzr, ne
+        ccmp    x1, xzr, #0x8, ne
+        cneg    x1, x1, ge
+        cneg    x6, x6, ge
+        csel    x4, x5, x4, ge
+        add     x5, x5, x6
+        add     x1, x1, #0x2
+        asr     x5, x5, #1
+        add     x12, x4, #0x100, lsl #12
+        sbfx    x12, x12, #22, #21
+        mov     x15, #0x100000
+        add     x15, x15, x15, lsl #21
+        add     x13, x4, x15
+        asr     x13, x13, #43
+        add     x14, x5, #0x100, lsl #12
+        sbfx    x14, x14, #22, #21
+        add     x15, x5, x15
+        asr     x15, x15, #43
+        mneg    x2, x12, x8
+        mneg    x3, x12, x9
+        mneg    x4, x14, x8
+        mneg    x5, x14, x9
+        msub    x10, x13, x16, x2
+        msub    x11, x13, x17, x3
+        msub    x12, x15, x16, x4
+        msub    x13, x15, x17, x5
+        mov     x22, x1
+        subs    x21, x21, #0x1
+        b.ne    Ledwards25519_scalarmulbase_alt_invloop
+        ldr     x0, [sp]
+        ldr     x1, [sp, #32]
+        mul     x0, x0, x10
+        madd    x1, x1, x11, x0
+        asr     x0, x1, #63
+        cmp     x10, xzr
+        csetm   x14, mi
+        cneg    x10, x10, mi
+        eor     x14, x14, x0
+        cmp     x11, xzr
+        csetm   x15, mi
+        cneg    x11, x11, mi
+        eor     x15, x15, x0
+        cmp     x12, xzr
+        csetm   x16, mi
+        cneg    x12, x12, mi
+        eor     x16, x16, x0
+        cmp     x13, xzr
+        csetm   x17, mi
+        cneg    x13, x13, mi
+        eor     x17, x17, x0
+        and     x0, x10, x14
+        and     x1, x11, x15
+        add     x9, x0, x1
+        ldr     x7, [sp, #64]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x4, x9, x0
+        adc     x2, xzr, x1
+        ldr     x8, [sp, #96]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x4, x4, x0
+        str     x4, [sp, #64]
+        adc     x2, x2, x1
+        ldr     x7, [sp, #72]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x2, x2, x0
+        adc     x6, xzr, x1
+        ldr     x8, [sp, #104]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x2, x2, x0
+        str     x2, [sp, #72]
+        adc     x6, x6, x1
+        ldr     x7, [sp, #80]
+        eor     x1, x7, x14
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x6, x6, x0
+        adc     x5, xzr, x1
+        ldr     x8, [sp, #112]
+        eor     x1, x8, x15
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x6, x6, x0
+        str     x6, [sp, #80]
+        adc     x5, x5, x1
+        ldr     x7, [sp, #88]
+        eor     x1, x7, x14
+        and     x3, x14, x10
+        neg     x3, x3
+        mul     x0, x1, x10
+        umulh   x1, x1, x10
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        ldr     x8, [sp, #120]
+        eor     x1, x8, x15
+        and     x0, x15, x11
+        sub     x3, x3, x0
+        mul     x0, x1, x11
+        umulh   x1, x1, x11
+        adds    x5, x5, x0
+        adc     x3, x3, x1
+        extr    x6, x3, x5, #63
+        ldp     x0, x1, [sp, #64]
+        tst     x3, x3
+        cinc    x6, x6, pl
+        mov     x3, #0x13
+        mul     x4, x6, x3
+        add     x5, x5, x6, lsl #63
+        smulh   x6, x6, x3
+        ldr     x2, [sp, #80]
+        adds    x0, x0, x4
+        adcs    x1, x1, x6
+        asr     x6, x6, #63
+        adcs    x2, x2, x6
+        adcs    x5, x5, x6
+        csel    x3, x3, xzr, mi
+        subs    x0, x0, x3
+        sbcs    x1, x1, xzr
+        sbcs    x2, x2, xzr
+        sbc     x5, x5, xzr
+        and     x5, x5, #0x7fffffffffffffff
+        mov     x4, x20
+        stp     x0, x1, [x4]
+        stp     x2, x5, [x4, #16]
+
+// The final result is x = X * inv(Z), y = Y * inv(Z).
+// These are the only operations in the whole computation that
+// fully reduce modulo p_25519 since now we want the canonical
+// answer as output.
+
+        mul_p25519(resx,x_3,w_3)
+        mul_p25519(resy,y_3,w_3)
+
+// Restore stack and registers
+
+        CFI_INC_SP(NSPACE)
+        CFI_POP2(x23,x24)
+        CFI_POP2(x21,x22)
+        CFI_POP2(x19,x20)
+
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
+
+// ****************************************************************************
+// The precomputed data (all read-only).
+// ****************************************************************************
+
+#if defined(__ELF__)
+.section .rodata
+.type S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant), %object
+.size S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant), 48576
+#elif defined(__APPLE__)
+.const_data
+#endif
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant):
+
+// 0 * B = 0 and 2^251 * B in extended-projective coordinates
+// but with Z = 1 assumed and hence left out, so they are (X,Y,T) only.
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000001
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x525f946d7c7220e7
+        .quad   0x4636b0b2f1e35444
+        .quad   0x796e9d70e892ae0f
+        .quad   0x03dec05fa937adb1
+        .quad   0x6d1c271cc6375515
+        .quad   0x462588c4a4ca4f14
+        .quad   0x691129fee55afc39
+        .quad   0x15949f784d8472f5
+        .quad   0xbd89e510afad0049
+        .quad   0x4d1f08c073b9860e
+        .quad   0x07716e8b2d00af9d
+        .quad   0x70d685f68f859714
+
+// Precomputed table of multiples of generator for edwards25519
+// all in precomputed extended-projective (y-x,x+y,2*d*x*y) triples.
+
+        // 2^0 * 1 * G
+
+        .quad   0x9d103905d740913e
+        .quad   0xfd399f05d140beb3
+        .quad   0xa5c18434688f8a09
+        .quad   0x44fd2f9298f81267
+        .quad   0x2fbc93c6f58c3b85
+        .quad   0xcf932dc6fb8c0e19
+        .quad   0x270b4898643d42c2
+        .quad   0x07cf9d3a33d4ba65
+        .quad   0xabc91205877aaa68
+        .quad   0x26d9e823ccaac49e
+        .quad   0x5a1b7dcbdd43598c
+        .quad   0x6f117b689f0c65a8
+
+        // 2^0 * 2 * G
+
+        .quad   0x8a99a56042b4d5a8
+        .quad   0x8f2b810c4e60acf6
+        .quad   0xe09e236bb16e37aa
+        .quad   0x6bb595a669c92555
+        .quad   0x9224e7fc933c71d7
+        .quad   0x9f469d967a0ff5b5
+        .quad   0x5aa69a65e1d60702
+        .quad   0x590c063fa87d2e2e
+        .quad   0x43faa8b3a59b7a5f
+        .quad   0x36c16bdd5d9acf78
+        .quad   0x500fa0840b3d6a31
+        .quad   0x701af5b13ea50b73
+
+        // 2^0 * 3 * G
+
+        .quad   0x56611fe8a4fcd265
+        .quad   0x3bd353fde5c1ba7d
+        .quad   0x8131f31a214bd6bd
+        .quad   0x2ab91587555bda62
+        .quad   0xaf25b0a84cee9730
+        .quad   0x025a8430e8864b8a
+        .quad   0xc11b50029f016732
+        .quad   0x7a164e1b9a80f8f4
+        .quad   0x14ae933f0dd0d889
+        .quad   0x589423221c35da62
+        .quad   0xd170e5458cf2db4c
+        .quad   0x5a2826af12b9b4c6
+
+        // 2^0 * 4 * G
+
+        .quad   0x95fe050a056818bf
+        .quad   0x327e89715660faa9
+        .quad   0xc3e8e3cd06a05073
+        .quad   0x27933f4c7445a49a
+        .quad   0x287351b98efc099f
+        .quad   0x6765c6f47dfd2538
+        .quad   0xca348d3dfb0a9265
+        .quad   0x680e910321e58727
+        .quad   0x5a13fbe9c476ff09
+        .quad   0x6e9e39457b5cc172
+        .quad   0x5ddbdcf9102b4494
+        .quad   0x7f9d0cbf63553e2b
+
+        // 2^0 * 5 * G
+
+        .quad   0x7f9182c3a447d6ba
+        .quad   0xd50014d14b2729b7
+        .quad   0xe33cf11cb864a087
+        .quad   0x154a7e73eb1b55f3
+        .quad   0xa212bc4408a5bb33
+        .quad   0x8d5048c3c75eed02
+        .quad   0xdd1beb0c5abfec44
+        .quad   0x2945ccf146e206eb
+        .quad   0xbcbbdbf1812a8285
+        .quad   0x270e0807d0bdd1fc
+        .quad   0xb41b670b1bbda72d
+        .quad   0x43aabe696b3bb69a
+
+        // 2^0 * 6 * G
+
+        .quad   0x499806b67b7d8ca4
+        .quad   0x575be28427d22739
+        .quad   0xbb085ce7204553b9
+        .quad   0x38b64c41ae417884
+        .quad   0x3a0ceeeb77157131
+        .quad   0x9b27158900c8af88
+        .quad   0x8065b668da59a736
+        .quad   0x51e57bb6a2cc38bd
+        .quad   0x85ac326702ea4b71
+        .quad   0xbe70e00341a1bb01
+        .quad   0x53e4a24b083bc144
+        .quad   0x10b8e91a9f0d61e3
+
+        // 2^0 * 7 * G
+
+        .quad   0xba6f2c9aaa3221b1
+        .quad   0x6ca021533bba23a7
+        .quad   0x9dea764f92192c3a
+        .quad   0x1d6edd5d2e5317e0
+        .quad   0x6b1a5cd0944ea3bf
+        .quad   0x7470353ab39dc0d2
+        .quad   0x71b2528228542e49
+        .quad   0x461bea69283c927e
+        .quad   0xf1836dc801b8b3a2
+        .quad   0xb3035f47053ea49a
+        .quad   0x529c41ba5877adf3
+        .quad   0x7a9fbb1c6a0f90a7
+
+        // 2^0 * 8 * G
+
+        .quad   0xe2a75dedf39234d9
+        .quad   0x963d7680e1b558f9
+        .quad   0x2c2741ac6e3c23fb
+        .quad   0x3a9024a1320e01c3
+        .quad   0x59b7596604dd3e8f
+        .quad   0x6cb30377e288702c
+        .quad   0xb1339c665ed9c323
+        .quad   0x0915e76061bce52f
+        .quad   0xe7c1f5d9c9a2911a
+        .quad   0xb8a371788bcca7d7
+        .quad   0x636412190eb62a32
+        .quad   0x26907c5c2ecc4e95
+
+        // 2^4 * 1 * B
+
+        .quad   0x7ec851ca553e2df3
+        .quad   0xa71284cba64878b3
+        .quad   0xe6b5e4193288d1e7
+        .quad   0x4cf210ec5a9a8883
+        .quad   0x322d04a52d9021f6
+        .quad   0xb9c19f3375c6bf9c
+        .quad   0x587a3a4342d20b09
+        .quad   0x143b1cf8aa64fe61
+        .quad   0x9f867c7d968acaab
+        .quad   0x5f54258e27092729
+        .quad   0xd0a7d34bea180975
+        .quad   0x21b546a3374126e1
+
+        // 2^4 * 2 * B
+
+        .quad   0xa94ff858a2888343
+        .quad   0xce0ed4565313ed3c
+        .quad   0xf55c3dcfb5bf34fa
+        .quad   0x0a653ca5c9eab371
+        .quad   0x490a7a45d185218f
+        .quad   0x9a15377846049335
+        .quad   0x0060ea09cc31e1f6
+        .quad   0x7e041577f86ee965
+        .quad   0x66b2a496ce5b67f3
+        .quad   0xff5492d8bd569796
+        .quad   0x503cec294a592cd0
+        .quad   0x566943650813acb2
+
+        // 2^4 * 3 * B
+
+        .quad   0xb818db0c26620798
+        .quad   0x5d5c31d9606e354a
+        .quad   0x0982fa4f00a8cdc7
+        .quad   0x17e12bcd4653e2d4
+        .quad   0x5672f9eb1dabb69d
+        .quad   0xba70b535afe853fc
+        .quad   0x47ac0f752796d66d
+        .quad   0x32a5351794117275
+        .quad   0xd3a644a6df648437
+        .quad   0x703b6559880fbfdd
+        .quad   0xcb852540ad3a1aa5
+        .quad   0x0900b3f78e4c6468
+
+        // 2^4 * 4 * B
+
+        .quad   0x0a851b9f679d651b
+        .quad   0xe108cb61033342f2
+        .quad   0xd601f57fe88b30a3
+        .quad   0x371f3acaed2dd714
+        .quad   0xed280fbec816ad31
+        .quad   0x52d9595bd8e6efe3
+        .quad   0x0fe71772f6c623f5
+        .quad   0x4314030b051e293c
+        .quad   0xd560005efbf0bcad
+        .quad   0x8eb70f2ed1870c5e
+        .quad   0x201f9033d084e6a0
+        .quad   0x4c3a5ae1ce7b6670
+
+        // 2^4 * 5 * B
+
+        .quad   0x4138a434dcb8fa95
+        .quad   0x870cf67d6c96840b
+        .quad   0xde388574297be82c
+        .quad   0x7c814db27262a55a
+        .quad   0xbaf875e4c93da0dd
+        .quad   0xb93282a771b9294d
+        .quad   0x80d63fb7f4c6c460
+        .quad   0x6de9c73dea66c181
+        .quad   0x478904d5a04df8f2
+        .quad   0xfafbae4ab10142d3
+        .quad   0xf6c8ac63555d0998
+        .quad   0x5aac4a412f90b104
+
+        // 2^4 * 6 * B
+
+        .quad   0xc64f326b3ac92908
+        .quad   0x5551b282e663e1e0
+        .quad   0x476b35f54a1a4b83
+        .quad   0x1b9da3fe189f68c2
+        .quad   0x603a0d0abd7f5134
+        .quad   0x8089c932e1d3ae46
+        .quad   0xdf2591398798bd63
+        .quad   0x1c145cd274ba0235
+        .quad   0x32e8386475f3d743
+        .quad   0x365b8baf6ae5d9ef
+        .quad   0x825238b6385b681e
+        .quad   0x234929c1167d65e1
+
+        // 2^4 * 7 * B
+
+        .quad   0x984decaba077ade8
+        .quad   0x383f77ad19eb389d
+        .quad   0xc7ec6b7e2954d794
+        .quad   0x59c77b3aeb7c3a7a
+        .quad   0x48145cc21d099fcf
+        .quad   0x4535c192cc28d7e5
+        .quad   0x80e7c1e548247e01
+        .quad   0x4a5f28743b2973ee
+        .quad   0xd3add725225ccf62
+        .quad   0x911a3381b2152c5d
+        .quad   0xd8b39fad5b08f87d
+        .quad   0x6f05606b4799fe3b
+
+        // 2^4 * 8 * B
+
+        .quad   0x9ffe9e92177ba962
+        .quad   0x98aee71d0de5cae1
+        .quad   0x3ff4ae942d831044
+        .quad   0x714de12e58533ac8
+        .quad   0x5b433149f91b6483
+        .quad   0xadb5dc655a2cbf62
+        .quad   0x87fa8412632827b3
+        .quad   0x60895e91ab49f8d8
+        .quad   0xe9ecf2ed0cf86c18
+        .quad   0xb46d06120735dfd4
+        .quad   0xbc9da09804b96be7
+        .quad   0x73e2e62fd96dc26b
+
+        // 2^8 * 1 * B
+
+        .quad   0xed5b635449aa515e
+        .quad   0xa865c49f0bc6823a
+        .quad   0x850c1fe95b42d1c4
+        .quad   0x30d76d6f03d315b9
+        .quad   0x2eccdd0e632f9c1d
+        .quad   0x51d0b69676893115
+        .quad   0x52dfb76ba8637a58
+        .quad   0x6dd37d49a00eef39
+        .quad   0x6c4444172106e4c7
+        .quad   0xfb53d680928d7f69
+        .quad   0xb4739ea4694d3f26
+        .quad   0x10c697112e864bb0
+
+        // 2^8 * 2 * B
+
+        .quad   0x6493c4277dbe5fde
+        .quad   0x265d4fad19ad7ea2
+        .quad   0x0e00dfc846304590
+        .quad   0x25e61cabed66fe09
+        .quad   0x0ca62aa08358c805
+        .quad   0x6a3d4ae37a204247
+        .quad   0x7464d3a63b11eddc
+        .quad   0x03bf9baf550806ef
+        .quad   0x3f13e128cc586604
+        .quad   0x6f5873ecb459747e
+        .quad   0xa0b63dedcc1268f5
+        .quad   0x566d78634586e22c
+
+        // 2^8 * 3 * B
+
+        .quad   0x1637a49f9cc10834
+        .quad   0xbc8e56d5a89bc451
+        .quad   0x1cb5ec0f7f7fd2db
+        .quad   0x33975bca5ecc35d9
+        .quad   0xa1054285c65a2fd0
+        .quad   0x6c64112af31667c3
+        .quad   0x680ae240731aee58
+        .quad   0x14fba5f34793b22a
+        .quad   0x3cd746166985f7d4
+        .quad   0x593e5e84c9c80057
+        .quad   0x2fc3f2b67b61131e
+        .quad   0x14829cea83fc526c
+
+        // 2^8 * 4 * B
+
+        .quad   0xff437b8497dd95c2
+        .quad   0x6c744e30aa4eb5a7
+        .quad   0x9e0c5d613c85e88b
+        .quad   0x2fd9c71e5f758173
+        .quad   0x21e70b2f4e71ecb8
+        .quad   0xe656ddb940a477e3
+        .quad   0xbf6556cece1d4f80
+        .quad   0x05fc3bc4535d7b7e
+        .quad   0x24b8b3ae52afdedd
+        .quad   0x3495638ced3b30cf
+        .quad   0x33a4bc83a9be8195
+        .quad   0x373767475c651f04
+
+        // 2^8 * 5 * B
+
+        .quad   0x2fba99fd40d1add9
+        .quad   0xb307166f96f4d027
+        .quad   0x4363f05215f03bae
+        .quad   0x1fbea56c3b18f999
+        .quad   0x634095cb14246590
+        .quad   0xef12144016c15535
+        .quad   0x9e38140c8910bc60
+        .quad   0x6bf5905730907c8c
+        .quad   0x0fa778f1e1415b8a
+        .quad   0x06409ff7bac3a77e
+        .quad   0x6f52d7b89aa29a50
+        .quad   0x02521cf67a635a56
+
+        // 2^8 * 6 * B
+
+        .quad   0x513fee0b0a9d5294
+        .quad   0x8f98e75c0fdf5a66
+        .quad   0xd4618688bfe107ce
+        .quad   0x3fa00a7e71382ced
+        .quad   0xb1146720772f5ee4
+        .quad   0xe8f894b196079ace
+        .quad   0x4af8224d00ac824a
+        .quad   0x001753d9f7cd6cc4
+        .quad   0x3c69232d963ddb34
+        .quad   0x1dde87dab4973858
+        .quad   0xaad7d1f9a091f285
+        .quad   0x12b5fe2fa048edb6
+
+        // 2^8 * 7 * B
+
+        .quad   0x71f0fbc496fce34d
+        .quad   0x73b9826badf35bed
+        .quad   0xd2047261ff28c561
+        .quad   0x749b76f96fb1206f
+        .quad   0xdf2b7c26ad6f1e92
+        .quad   0x4b66d323504b8913
+        .quad   0x8c409dc0751c8bc3
+        .quad   0x6f7e93c20796c7b8
+        .quad   0x1f5af604aea6ae05
+        .quad   0xc12351f1bee49c99
+        .quad   0x61a808b5eeff6b66
+        .quad   0x0fcec10f01e02151
+
+        // 2^8 * 8 * B
+
+        .quad   0x644d58a649fe1e44
+        .quad   0x21fcaea231ad777e
+        .quad   0x02441c5a887fd0d2
+        .quad   0x4901aa7183c511f3
+        .quad   0x3df2d29dc4244e45
+        .quad   0x2b020e7493d8de0a
+        .quad   0x6cc8067e820c214d
+        .quad   0x413779166feab90a
+        .quad   0x08b1b7548c1af8f0
+        .quad   0xce0f7a7c246299b4
+        .quad   0xf760b0f91e06d939
+        .quad   0x41bb887b726d1213
+
+        // 2^12 * 1 * B
+
+        .quad   0x9267806c567c49d8
+        .quad   0x066d04ccca791e6a
+        .quad   0xa69f5645e3cc394b
+        .quad   0x5c95b686a0788cd2
+        .quad   0x97d980e0aa39f7d2
+        .quad   0x35d0384252c6b51c
+        .quad   0x7d43f49307cd55aa
+        .quad   0x56bd36cfb78ac362
+        .quad   0x2ac519c10d14a954
+        .quad   0xeaf474b494b5fa90
+        .quad   0xe6af8382a9f87a5a
+        .quad   0x0dea6db1879be094
+
+        // 2^12 * 2 * B
+
+        .quad   0xaa66bf547344e5ab
+        .quad   0xda1258888f1b4309
+        .quad   0x5e87d2b3fd564b2f
+        .quad   0x5b2c78885483b1dd
+        .quad   0x15baeb74d6a8797a
+        .quad   0x7ef55cf1fac41732
+        .quad   0x29001f5a3c8b05c5
+        .quad   0x0ad7cc8752eaccfb
+        .quad   0x52151362793408cf
+        .quad   0xeb0f170319963d94
+        .quad   0xa833b2fa883d9466
+        .quad   0x093a7fa775003c78
+
+        // 2^12 * 3 * B
+
+        .quad   0xe5107de63a16d7be
+        .quad   0xa377ffdc9af332cf
+        .quad   0x70d5bf18440b677f
+        .quad   0x6a252b19a4a31403
+        .quad   0xb8e9604460a91286
+        .quad   0x7f3fd8047778d3de
+        .quad   0x67d01e31bf8a5e2d
+        .quad   0x7b038a06c27b653e
+        .quad   0x9ed919d5d36990f3
+        .quad   0x5213aebbdb4eb9f2
+        .quad   0xc708ea054cb99135
+        .quad   0x58ded57f72260e56
+
+        // 2^12 * 4 * B
+
+        .quad   0x78e79dade9413d77
+        .quad   0xf257f9d59729e67d
+        .quad   0x59db910ee37aa7e6
+        .quad   0x6aa11b5bbb9e039c
+        .quad   0xda6d53265b0fd48b
+        .quad   0x8960823193bfa988
+        .quad   0xd78ac93261d57e28
+        .quad   0x79f2942d3a5c8143
+        .quad   0x97da2f25b6c88de9
+        .quad   0x251ba7eaacf20169
+        .quad   0x09b44f87ef4eb4e4
+        .quad   0x7d90ab1bbc6a7da5
+
+        // 2^12 * 5 * B
+
+        .quad   0x9acca683a7016bfe
+        .quad   0x90505f4df2c50b6d
+        .quad   0x6b610d5fcce435aa
+        .quad   0x19a10d446198ff96
+        .quad   0x1a07a3f496b3c397
+        .quad   0x11ceaa188f4e2532
+        .quad   0x7d9498d5a7751bf0
+        .quad   0x19ed161f508dd8a0
+        .quad   0x560a2cd687dce6ca
+        .quad   0x7f3568c48664cf4d
+        .quad   0x8741e95222803a38
+        .quad   0x483bdab1595653fc
+
+        // 2^12 * 6 * B
+
+        .quad   0xfa780f148734fa49
+        .quad   0x106f0b70360534e0
+        .quad   0x2210776fe3e307bd
+        .quad   0x3286c109dde6a0fe
+        .quad   0xd6cf4d0ab4da80f6
+        .quad   0x82483e45f8307fe0
+        .quad   0x05005269ae6f9da4
+        .quad   0x1c7052909cf7877a
+        .quad   0x32ee7de2874e98d4
+        .quad   0x14c362e9b97e0c60
+        .quad   0x5781dcde6a60a38a
+        .quad   0x217dd5eaaa7aa840
+
+        // 2^12 * 7 * B
+
+        .quad   0x9db7c4d0248e1eb0
+        .quad   0xe07697e14d74bf52
+        .quad   0x1e6a9b173c562354
+        .quad   0x7fa7c21f795a4965
+        .quad   0x8bdf1fb9be8c0ec8
+        .quad   0x00bae7f8e30a0282
+        .quad   0x4963991dad6c4f6c
+        .quad   0x07058a6e5df6f60a
+        .quad   0xe9eb02c4db31f67f
+        .quad   0xed25fd8910bcfb2b
+        .quad   0x46c8131f5c5cddb4
+        .quad   0x33b21c13a0cb9bce
+
+        // 2^12 * 8 * B
+
+        .quad   0x360692f8087d8e31
+        .quad   0xf4dcc637d27163f7
+        .quad   0x25a4e62065ea5963
+        .quad   0x659bf72e5ac160d9
+        .quad   0x9aafb9b05ee38c5b
+        .quad   0xbf9d2d4e071a13c7
+        .quad   0x8eee6e6de933290a
+        .quad   0x1c3bab17ae109717
+        .quad   0x1c9ab216c7cab7b0
+        .quad   0x7d65d37407bbc3cc
+        .quad   0x52744750504a58d5
+        .quad   0x09f2606b131a2990
+
+        // 2^16 * 1 * B
+
+        .quad   0x40e87d44744346be
+        .quad   0x1d48dad415b52b25
+        .quad   0x7c3a8a18a13b603e
+        .quad   0x4eb728c12fcdbdf7
+        .quad   0x7e234c597c6691ae
+        .quad   0x64889d3d0a85b4c8
+        .quad   0xdae2c90c354afae7
+        .quad   0x0a871e070c6a9e1d
+        .quad   0x3301b5994bbc8989
+        .quad   0x736bae3a5bdd4260
+        .quad   0x0d61ade219d59e3c
+        .quad   0x3ee7300f2685d464
+
+        // 2^16 * 2 * B
+
+        .quad   0xf5d255e49e7dd6b7
+        .quad   0x8016115c610b1eac
+        .quad   0x3c99975d92e187ca
+        .quad   0x13815762979125c2
+        .quad   0x43fa7947841e7518
+        .quad   0xe5c6fa59639c46d7
+        .quad   0xa1065e1de3052b74
+        .quad   0x7d47c6a2cfb89030
+        .quad   0x3fdad0148ef0d6e0
+        .quad   0x9d3e749a91546f3c
+        .quad   0x71ec621026bb8157
+        .quad   0x148cf58d34c9ec80
+
+        // 2^16 * 3 * B
+
+        .quad   0x46a492f67934f027
+        .quad   0x469984bef6840aa9
+        .quad   0x5ca1bc2a89611854
+        .quad   0x3ff2fa1ebd5dbbd4
+        .quad   0xe2572f7d9ae4756d
+        .quad   0x56c345bb88f3487f
+        .quad   0x9fd10b6d6960a88d
+        .quad   0x278febad4eaea1b9
+        .quad   0xb1aa681f8c933966
+        .quad   0x8c21949c20290c98
+        .quad   0x39115291219d3c52
+        .quad   0x4104dd02fe9c677b
+
+        // 2^16 * 4 * B
+
+        .quad   0x72b2bf5e1124422a
+        .quad   0xa1fa0c3398a33ab5
+        .quad   0x94cb6101fa52b666
+        .quad   0x2c863b00afaf53d5
+        .quad   0x81214e06db096ab8
+        .quad   0x21a8b6c90ce44f35
+        .quad   0x6524c12a409e2af5
+        .quad   0x0165b5a48efca481
+        .quad   0xf190a474a0846a76
+        .quad   0x12eff984cd2f7cc0
+        .quad   0x695e290658aa2b8f
+        .quad   0x591b67d9bffec8b8
+
+        // 2^16 * 5 * B
+
+        .quad   0x312f0d1c80b49bfa
+        .quad   0x5979515eabf3ec8a
+        .quad   0x727033c09ef01c88
+        .quad   0x3de02ec7ca8f7bcb
+        .quad   0x99b9b3719f18b55d
+        .quad   0xe465e5faa18c641e
+        .quad   0x61081136c29f05ed
+        .quad   0x489b4f867030128b
+        .quad   0xd232102d3aeb92ef
+        .quad   0xe16253b46116a861
+        .quad   0x3d7eabe7190baa24
+        .quad   0x49f5fbba496cbebf
+
+        // 2^16 * 6 * B
+
+        .quad   0x30949a108a5bcfd4
+        .quad   0xdc40dd70bc6473eb
+        .quad   0x92c294c1307c0d1c
+        .quad   0x5604a86dcbfa6e74
+        .quad   0x155d628c1e9c572e
+        .quad   0x8a4d86acc5884741
+        .quad   0x91a352f6515763eb
+        .quad   0x06a1a6c28867515b
+        .quad   0x7288d1d47c1764b6
+        .quad   0x72541140e0418b51
+        .quad   0x9f031a6018acf6d1
+        .quad   0x20989e89fe2742c6
+
+        // 2^16 * 7 * B
+
+        .quad   0x499777fd3a2dcc7f
+        .quad   0x32857c2ca54fd892
+        .quad   0xa279d864d207e3a0
+        .quad   0x0403ed1d0ca67e29
+        .quad   0x1674278b85eaec2e
+        .quad   0x5621dc077acb2bdf
+        .quad   0x640a4c1661cbf45a
+        .quad   0x730b9950f70595d3
+        .quad   0xc94b2d35874ec552
+        .quad   0xc5e6c8cf98246f8d
+        .quad   0xf7cb46fa16c035ce
+        .quad   0x5bd7454308303dcc
+
+        // 2^16 * 8 * B
+
+        .quad   0x7f9ad19528b24cc2
+        .quad   0x7f6b54656335c181
+        .quad   0x66b8b66e4fc07236
+        .quad   0x133a78007380ad83
+        .quad   0x85c4932115e7792a
+        .quad   0xc64c89a2bdcdddc9
+        .quad   0x9d1e3da8ada3d762
+        .quad   0x5bb7db123067f82c
+        .quad   0x0961f467c6ca62be
+        .quad   0x04ec21d6211952ee
+        .quad   0x182360779bd54770
+        .quad   0x740dca6d58f0e0d2
+
+        // 2^20 * 1 * B
+
+        .quad   0x50b70bf5d3f0af0b
+        .quad   0x4feaf48ae32e71f7
+        .quad   0x60e84ed3a55bbd34
+        .quad   0x00ed489b3f50d1ed
+        .quad   0x3906c72aed261ae5
+        .quad   0x9ab68fd988e100f7
+        .quad   0xf5e9059af3360197
+        .quad   0x0e53dc78bf2b6d47
+        .quad   0xb90829bf7971877a
+        .quad   0x5e4444636d17e631
+        .quad   0x4d05c52e18276893
+        .quad   0x27632d9a5a4a4af5
+
+        // 2^20 * 2 * B
+
+        .quad   0xd11ff05154b260ce
+        .quad   0xd86dc38e72f95270
+        .quad   0x601fcd0d267cc138
+        .quad   0x2b67916429e90ccd
+        .quad   0xa98285d187eaffdb
+        .quad   0xa5b4fbbbd8d0a864
+        .quad   0xb658f27f022663f7
+        .quad   0x3bbc2b22d99ce282
+        .quad   0xb917c952583c0a58
+        .quad   0x653ff9b80fe4c6f3
+        .quad   0x9b0da7d7bcdf3c0c
+        .quad   0x43a0eeb6ab54d60e
+
+        // 2^20 * 3 * B
+
+        .quad   0x396966a46d4a5487
+        .quad   0xf811a18aac2bb3ba
+        .quad   0x66e4685b5628b26b
+        .quad   0x70a477029d929b92
+        .quad   0x3ac6322357875fe8
+        .quad   0xd9d4f4ecf5fbcb8f
+        .quad   0x8dee8493382bb620
+        .quad   0x50c5eaa14c799fdc
+        .quad   0xdd0edc8bd6f2fb3c
+        .quad   0x54c63aa79cc7b7a0
+        .quad   0xae0b032b2c8d9f1a
+        .quad   0x6f9ce107602967fb
+
+        // 2^20 * 4 * B
+
+        .quad   0xad1054b1cde1c22a
+        .quad   0xc4a8e90248eb32df
+        .quad   0x5f3e7b33accdc0ea
+        .quad   0x72364713fc79963e
+        .quad   0x139693063520e0b5
+        .quad   0x437fcf7c88ea03fe
+        .quad   0xf7d4c40bd3c959bc
+        .quad   0x699154d1f893ded9
+        .quad   0x315d5c75b4b27526
+        .quad   0xcccb842d0236daa5
+        .quad   0x22f0c8a3345fee8e
+        .quad   0x73975a617d39dbed
+
+        // 2^20 * 5 * B
+
+        .quad   0xe4024df96375da10
+        .quad   0x78d3251a1830c870
+        .quad   0x902b1948658cd91c
+        .quad   0x7e18b10b29b7438a
+        .quad   0x6f37f392f4433e46
+        .quad   0x0e19b9a11f566b18
+        .quad   0x220fb78a1fd1d662
+        .quad   0x362a4258a381c94d
+        .quad   0x9071d9132b6beb2f
+        .quad   0x0f26e9ad28418247
+        .quad   0xeab91ec9bdec925d
+        .quad   0x4be65bc8f48af2de
+
+        // 2^20 * 6 * B
+
+        .quad   0x78487feba36e7028
+        .quad   0x5f3f13001dd8ce34
+        .quad   0x934fb12d4b30c489
+        .quad   0x056c244d397f0a2b
+        .quad   0x1d50fba257c26234
+        .quad   0x7bd4823adeb0678b
+        .quad   0xc2b0dc6ea6538af5
+        .quad   0x5665eec6351da73e
+        .quad   0xdb3ee00943bfb210
+        .quad   0x4972018720800ac2
+        .quad   0x26ab5d6173bd8667
+        .quad   0x20b209c2ab204938
+
+        // 2^20 * 7 * B
+
+        .quad   0x549e342ac07fb34b
+        .quad   0x02d8220821373d93
+        .quad   0xbc262d70acd1f567
+        .quad   0x7a92c9fdfbcac784
+        .quad   0x1fcca94516bd3289
+        .quad   0x448d65aa41420428
+        .quad   0x59c3b7b216a55d62
+        .quad   0x49992cc64e612cd8
+        .quad   0x65bd1bea70f801de
+        .quad   0x1befb7c0fe49e28a
+        .quad   0xa86306cdb1b2ae4a
+        .quad   0x3b7ac0cd265c2a09
+
+        // 2^20 * 8 * B
+
+        .quad   0x822bee438c01bcec
+        .quad   0x530cb525c0fbc73b
+        .quad   0x48519034c1953fe9
+        .quad   0x265cc261e09a0f5b
+        .quad   0xf0d54e4f22ed39a7
+        .quad   0xa2aae91e5608150a
+        .quad   0xf421b2e9eddae875
+        .quad   0x31bc531d6b7de992
+        .quad   0xdf3d134da980f971
+        .quad   0x7a4fb8d1221a22a7
+        .quad   0x3df7d42035aad6d8
+        .quad   0x2a14edcc6a1a125e
+
+        // 2^24 * 1 * B
+
+        .quad   0xdf48ee0752cfce4e
+        .quad   0xc3fffaf306ec08b7
+        .quad   0x05710b2ab95459c4
+        .quad   0x161d25fa963ea38d
+        .quad   0x231a8c570478433c
+        .quad   0xb7b5270ec281439d
+        .quad   0xdbaa99eae3d9079f
+        .quad   0x2c03f5256c2b03d9
+        .quad   0x790f18757b53a47d
+        .quad   0x307b0130cf0c5879
+        .quad   0x31903d77257ef7f9
+        .quad   0x699468bdbd96bbaf
+
+        // 2^24 * 2 * B
+
+        .quad   0xbd1f2f46f4dafecf
+        .quad   0x7cef0114a47fd6f7
+        .quad   0xd31ffdda4a47b37f
+        .quad   0x525219a473905785
+        .quad   0xd8dd3de66aa91948
+        .quad   0x485064c22fc0d2cc
+        .quad   0x9b48246634fdea2f
+        .quad   0x293e1c4e6c4a2e3a
+        .quad   0x376e134b925112e1
+        .quad   0x703778b5dca15da0
+        .quad   0xb04589af461c3111
+        .quad   0x5b605c447f032823
+
+        // 2^24 * 3 * B
+
+        .quad   0xb965805920c47c89
+        .quad   0xe7f0100c923b8fcc
+        .quad   0x0001256502e2ef77
+        .quad   0x24a76dcea8aeb3ee
+        .quad   0x3be9fec6f0e7f04c
+        .quad   0x866a579e75e34962
+        .quad   0x5542ef161e1de61a
+        .quad   0x2f12fef4cc5abdd5
+        .quad   0x0a4522b2dfc0c740
+        .quad   0x10d06e7f40c9a407
+        .quad   0xc6cf144178cff668
+        .quad   0x5e607b2518a43790
+
+        // 2^24 * 4 * B
+
+        .quad   0x58b31d8f6cdf1818
+        .quad   0x35cfa74fc36258a2
+        .quad   0xe1b3ff4f66e61d6e
+        .quad   0x5067acab6ccdd5f7
+        .quad   0xa02c431ca596cf14
+        .quad   0xe3c42d40aed3e400
+        .quad   0xd24526802e0f26db
+        .quad   0x201f33139e457068
+        .quad   0xfd527f6b08039d51
+        .quad   0x18b14964017c0006
+        .quad   0xd5220eb02e25a4a8
+        .quad   0x397cba8862460375
+
+        // 2^24 * 5 * B
+
+        .quad   0x30c13093f05959b2
+        .quad   0xe23aa18de9a97976
+        .quad   0x222fd491721d5e26
+        .quad   0x2339d320766e6c3a
+        .quad   0x7815c3fbc81379e7
+        .quad   0xa6619420dde12af1
+        .quad   0xffa9c0f885a8fdd5
+        .quad   0x771b4022c1e1c252
+        .quad   0xd87dd986513a2fa7
+        .quad   0xf5ac9b71f9d4cf08
+        .quad   0xd06bc31b1ea283b3
+        .quad   0x331a189219971a76
+
+        // 2^24 * 6 * B
+
+        .quad   0xf5166f45fb4f80c6
+        .quad   0x9c36c7de61c775cf
+        .quad   0xe3d4e81b9041d91c
+        .quad   0x31167c6b83bdfe21
+        .quad   0x26512f3a9d7572af
+        .quad   0x5bcbe28868074a9e
+        .quad   0x84edc1c11180f7c4
+        .quad   0x1ac9619ff649a67b
+        .quad   0xf22b3842524b1068
+        .quad   0x5068343bee9ce987
+        .quad   0xfc9d71844a6250c8
+        .quad   0x612436341f08b111
+
+        // 2^24 * 7 * B
+
+        .quad   0xd99d41db874e898d
+        .quad   0x09fea5f16c07dc20
+        .quad   0x793d2c67d00f9bbc
+        .quad   0x46ebe2309e5eff40
+        .quad   0x8b6349e31a2d2638
+        .quad   0x9ddfb7009bd3fd35
+        .quad   0x7f8bf1b8a3a06ba4
+        .quad   0x1522aa3178d90445
+        .quad   0x2c382f5369614938
+        .quad   0xdafe409ab72d6d10
+        .quad   0xe8c83391b646f227
+        .quad   0x45fe70f50524306c
+
+        // 2^24 * 8 * B
+
+        .quad   0xda4875a6960c0b8c
+        .quad   0x5b68d076ef0e2f20
+        .quad   0x07fb51cf3d0b8fd4
+        .quad   0x428d1623a0e392d4
+        .quad   0x62f24920c8951491
+        .quad   0x05f007c83f630ca2
+        .quad   0x6fbb45d2f5c9d4b8
+        .quad   0x16619f6db57a2245
+        .quad   0x084f4a4401a308fd
+        .quad   0xa82219c376a5caac
+        .quad   0xdeb8de4643d1bc7d
+        .quad   0x1d81592d60bd38c6
+
+        // 2^28 * 1 * B
+
+        .quad   0xd833d7beec2a4c38
+        .quad   0x2c9162830acc20ed
+        .quad   0xe93a47aa92df7581
+        .quad   0x702d67a3333c4a81
+        .quad   0x3a4a369a2f89c8a1
+        .quad   0x63137a1d7c8de80d
+        .quad   0xbcac008a78eda015
+        .quad   0x2cb8b3a5b483b03f
+        .quad   0x36e417cbcb1b90a1
+        .quad   0x33b3ddaa7f11794e
+        .quad   0x3f510808885bc607
+        .quad   0x24141dc0e6a8020d
+
+        // 2^28 * 2 * B
+
+        .quad   0x59f73c773fefee9d
+        .quad   0xb3f1ef89c1cf989d
+        .quad   0xe35dfb42e02e545f
+        .quad   0x5766120b47a1b47c
+        .quad   0x91925dccbd83157d
+        .quad   0x3ca1205322cc8094
+        .quad   0x28e57f183f90d6e4
+        .quad   0x1a4714cede2e767b
+        .quad   0xdb20ba0fb8b6b7ff
+        .quad   0xb732c3b677511fa1
+        .quad   0xa92b51c099f02d89
+        .quad   0x4f3875ad489ca5f1
+
+        // 2^28 * 3 * B
+
+        .quad   0xc7fc762f4932ab22
+        .quad   0x7ac0edf72f4c3c1b
+        .quad   0x5f6b55aa9aa895e8
+        .quad   0x3680274dad0a0081
+        .quad   0x79ed13f6ee73eec0
+        .quad   0xa5c6526d69110bb1
+        .quad   0xe48928c38603860c
+        .quad   0x722a1446fd7059f5
+        .quad   0xd0959fe9a8cf8819
+        .quad   0xd0a995508475a99c
+        .quad   0x6eac173320b09cc5
+        .quad   0x628ecf04331b1095
+
+        // 2^28 * 4 * B
+
+        .quad   0x98bcb118a9d0ddbc
+        .quad   0xee449e3408b4802b
+        .quad   0x87089226b8a6b104
+        .quad   0x685f349a45c7915d
+        .quad   0x9b41acf85c74ccf1
+        .quad   0xb673318108265251
+        .quad   0x99c92aed11adb147
+        .quad   0x7a47d70d34ecb40f
+        .quad   0x60a0c4cbcc43a4f5
+        .quad   0x775c66ca3677bea9
+        .quad   0xa17aa1752ff8f5ed
+        .quad   0x11ded9020e01fdc0
+
+        // 2^28 * 5 * B
+
+        .quad   0x890e7809caefe704
+        .quad   0x8728296de30e8c6c
+        .quad   0x4c5cd2a392aeb1c9
+        .quad   0x194263d15771531f
+        .quad   0x471f95b03bea93b7
+        .quad   0x0552d7d43313abd3
+        .quad   0xbd9370e2e17e3f7b
+        .quad   0x7b120f1db20e5bec
+        .quad   0x17d2fb3d86502d7a
+        .quad   0xb564d84450a69352
+        .quad   0x7da962c8a60ed75d
+        .quad   0x00d0f85b318736aa
+
+        // 2^28 * 6 * B
+
+        .quad   0x978b142e777c84fd
+        .quad   0xf402644705a8c062
+        .quad   0xa67ad51be7e612c7
+        .quad   0x2f7b459698dd6a33
+        .quad   0xa6753c1efd7621c1
+        .quad   0x69c0b4a7445671f5
+        .quad   0x971f527405b23c11
+        .quad   0x387bc74851a8c7cd
+        .quad   0x81894b4d4a52a9a8
+        .quad   0xadd93e12f6b8832f
+        .quad   0x184d8548b61bd638
+        .quad   0x3f1c62dbd6c9f6cd
+
+        // 2^28 * 7 * B
+
+        .quad   0x2e8f1f0091910c1f
+        .quad   0xa4df4fe0bff2e12c
+        .quad   0x60c6560aee927438
+        .quad   0x6338283facefc8fa
+        .quad   0x3fad3e40148f693d
+        .quad   0x052656e194eb9a72
+        .quad   0x2f4dcbfd184f4e2f
+        .quad   0x406f8db1c482e18b
+        .quad   0x9e630d2c7f191ee4
+        .quad   0x4fbf8301bc3ff670
+        .quad   0x787d8e4e7afb73c4
+        .quad   0x50d83d5be8f58fa5
+
+        // 2^28 * 8 * B
+
+        .quad   0x85683916c11a1897
+        .quad   0x2d69a4efe506d008
+        .quad   0x39af1378f664bd01
+        .quad   0x65942131361517c6
+        .quad   0xc0accf90b4d3b66d
+        .quad   0xa7059de561732e60
+        .quad   0x033d1f7870c6b0ba
+        .quad   0x584161cd26d946e4
+        .quad   0xbbf2b1a072d27ca2
+        .quad   0xbf393c59fbdec704
+        .quad   0xe98dbbcee262b81e
+        .quad   0x02eebd0b3029b589
+
+        // 2^32 * 1 * B
+
+        .quad   0x61368756a60dac5f
+        .quad   0x17e02f6aebabdc57
+        .quad   0x7f193f2d4cce0f7d
+        .quad   0x20234a7789ecdcf0
+        .quad   0x8765b69f7b85c5e8
+        .quad   0x6ff0678bd168bab2
+        .quad   0x3a70e77c1d330f9b
+        .quad   0x3a5f6d51b0af8e7c
+        .quad   0x76d20db67178b252
+        .quad   0x071c34f9d51ed160
+        .quad   0xf62a4a20b3e41170
+        .quad   0x7cd682353cffe366
+
+        // 2^32 * 2 * B
+
+        .quad   0x0be1a45bd887fab6
+        .quad   0x2a846a32ba403b6e
+        .quad   0xd9921012e96e6000
+        .quad   0x2838c8863bdc0943
+        .quad   0xa665cd6068acf4f3
+        .quad   0x42d92d183cd7e3d3
+        .quad   0x5759389d336025d9
+        .quad   0x3ef0253b2b2cd8ff
+        .quad   0xd16bb0cf4a465030
+        .quad   0xfa496b4115c577ab
+        .quad   0x82cfae8af4ab419d
+        .quad   0x21dcb8a606a82812
+
+        // 2^32 * 3 * B
+
+        .quad   0x5c6004468c9d9fc8
+        .quad   0x2540096ed42aa3cb
+        .quad   0x125b4d4c12ee2f9c
+        .quad   0x0bc3d08194a31dab
+        .quad   0x9a8d00fabe7731ba
+        .quad   0x8203607e629e1889
+        .quad   0xb2cc023743f3d97f
+        .quad   0x5d840dbf6c6f678b
+        .quad   0x706e380d309fe18b
+        .quad   0x6eb02da6b9e165c7
+        .quad   0x57bbba997dae20ab
+        .quad   0x3a4276232ac196dd
+
+        // 2^32 * 4 * B
+
+        .quad   0x4b42432c8a7084fa
+        .quad   0x898a19e3dfb9e545
+        .quad   0xbe9f00219c58e45d
+        .quad   0x1ff177cea16debd1
+        .quad   0x3bf8c172db447ecb
+        .quad   0x5fcfc41fc6282dbd
+        .quad   0x80acffc075aa15fe
+        .quad   0x0770c9e824e1a9f9
+        .quad   0xcf61d99a45b5b5fd
+        .quad   0x860984e91b3a7924
+        .quad   0xe7300919303e3e89
+        .quad   0x39f264fd41500b1e
+
+        // 2^32 * 5 * B
+
+        .quad   0xa7ad3417dbe7e29c
+        .quad   0xbd94376a2b9c139c
+        .quad   0xa0e91b8e93597ba9
+        .quad   0x1712d73468889840
+        .quad   0xd19b4aabfe097be1
+        .quad   0xa46dfce1dfe01929
+        .quad   0xc3c908942ca6f1ff
+        .quad   0x65c621272c35f14e
+        .quad   0xe72b89f8ce3193dd
+        .quad   0x4d103356a125c0bb
+        .quad   0x0419a93d2e1cfe83
+        .quad   0x22f9800ab19ce272
+
+        // 2^32 * 6 * B
+
+        .quad   0x605a368a3e9ef8cb
+        .quad   0xe3e9c022a5504715
+        .quad   0x553d48b05f24248f
+        .quad   0x13f416cd647626e5
+        .quad   0x42029fdd9a6efdac
+        .quad   0xb912cebe34a54941
+        .quad   0x640f64b987bdf37b
+        .quad   0x4171a4d38598cab4
+        .quad   0xfa2758aa99c94c8c
+        .quad   0x23006f6fb000b807
+        .quad   0xfbd291ddadda5392
+        .quad   0x508214fa574bd1ab
+
+        // 2^32 * 7 * B
+
+        .quad   0xc20269153ed6fe4b
+        .quad   0xa65a6739511d77c4
+        .quad   0xcbde26462c14af94
+        .quad   0x22f960ec6faba74b
+        .quad   0x461a15bb53d003d6
+        .quad   0xb2102888bcf3c965
+        .quad   0x27c576756c683a5a
+        .quad   0x3a7758a4c86cb447
+        .quad   0x548111f693ae5076
+        .quad   0x1dae21df1dfd54a6
+        .quad   0x12248c90f3115e65
+        .quad   0x5d9fd15f8de7f494
+
+        // 2^32 * 8 * B
+
+        .quad   0x031408d36d63727f
+        .quad   0x6a379aefd7c7b533
+        .quad   0xa9e18fc5ccaee24b
+        .quad   0x332f35914f8fbed3
+        .quad   0x3f244d2aeed7521e
+        .quad   0x8e3a9028432e9615
+        .quad   0xe164ba772e9c16d4
+        .quad   0x3bc187fa47eb98d8
+        .quad   0x6d470115ea86c20c
+        .quad   0x998ab7cb6c46d125
+        .quad   0xd77832b53a660188
+        .quad   0x450d81ce906fba03
+
+        // 2^36 * 1 * B
+
+        .quad   0xf8ae4d2ad8453902
+        .quad   0x7018058ee8db2d1d
+        .quad   0xaab3995fc7d2c11e
+        .quad   0x53b16d2324ccca79
+        .quad   0x23264d66b2cae0b5
+        .quad   0x7dbaed33ebca6576
+        .quad   0x030ebed6f0d24ac8
+        .quad   0x2a887f78f7635510
+        .quad   0x2a23b9e75c012d4f
+        .quad   0x0c974651cae1f2ea
+        .quad   0x2fb63273675d70ca
+        .quad   0x0ba7250b864403f5
+
+        // 2^36 * 2 * B
+
+        .quad   0xbb0d18fd029c6421
+        .quad   0xbc2d142189298f02
+        .quad   0x8347f8e68b250e96
+        .quad   0x7b9f2fe8032d71c9
+        .quad   0xdd63589386f86d9c
+        .quad   0x61699176e13a85a4
+        .quad   0x2e5111954eaa7d57
+        .quad   0x32c21b57fb60bdfb
+        .quad   0xd87823cd319e0780
+        .quad   0xefc4cfc1897775c5
+        .quad   0x4854fb129a0ab3f7
+        .quad   0x12c49d417238c371
+
+        // 2^36 * 3 * B
+
+        .quad   0x0950b533ffe83769
+        .quad   0x21861c1d8e1d6bd1
+        .quad   0xf022d8381302e510
+        .quad   0x2509200c6391cab4
+        .quad   0x09b3a01783799542
+        .quad   0x626dd08faad5ee3f
+        .quad   0xba00bceeeb70149f
+        .quad   0x1421b246a0a444c9
+        .quad   0x4aa43a8e8c24a7c7
+        .quad   0x04c1f540d8f05ef5
+        .quad   0xadba5e0c0b3eb9dc
+        .quad   0x2ab5504448a49ce3
+
+        // 2^36 * 4 * B
+
+        .quad   0x2ed227266f0f5dec
+        .quad   0x9824ee415ed50824
+        .quad   0x807bec7c9468d415
+        .quad   0x7093bae1b521e23f
+        .quad   0xdc07ac631c5d3afa
+        .quad   0x58615171f9df8c6c
+        .quad   0x72a079d89d73e2b0
+        .quad   0x7301f4ceb4eae15d
+        .quad   0x6409e759d6722c41
+        .quad   0xa674e1cf72bf729b
+        .quad   0xbc0a24eb3c21e569
+        .quad   0x390167d24ebacb23
+
+        // 2^36 * 5 * B
+
+        .quad   0x27f58e3bba353f1c
+        .quad   0x4c47764dbf6a4361
+        .quad   0xafbbc4e56e562650
+        .quad   0x07db2ee6aae1a45d
+        .quad   0xd7bb054ba2f2120b
+        .quad   0xe2b9ceaeb10589b7
+        .quad   0x3fe8bac8f3c0edbe
+        .quad   0x4cbd40767112cb69
+        .quad   0x0b603cc029c58176
+        .quad   0x5988e3825cb15d61
+        .quad   0x2bb61413dcf0ad8d
+        .quad   0x7b8eec6c74183287
+
+        // 2^36 * 6 * B
+
+        .quad   0xe4ca40782cd27cb0
+        .quad   0xdaf9c323fbe967bd
+        .quad   0xb29bd34a8ad41e9e
+        .quad   0x72810497626ede4d
+        .quad   0x32fee570fc386b73
+        .quad   0xda8b0141da3a8cc7
+        .quad   0x975ffd0ac8968359
+        .quad   0x6ee809a1b132a855
+        .quad   0x9444bb31fcfd863a
+        .quad   0x2fe3690a3e4e48c5
+        .quad   0xdc29c867d088fa25
+        .quad   0x13bd1e38d173292e
+
+        // 2^36 * 7 * B
+
+        .quad   0xd32b4cd8696149b5
+        .quad   0xe55937d781d8aab7
+        .quad   0x0bcb2127ae122b94
+        .quad   0x41e86fcfb14099b0
+        .quad   0x223fb5cf1dfac521
+        .quad   0x325c25316f554450
+        .quad   0x030b98d7659177ac
+        .quad   0x1ed018b64f88a4bd
+        .quad   0x3630dfa1b802a6b0
+        .quad   0x880f874742ad3bd5
+        .quad   0x0af90d6ceec5a4d4
+        .quad   0x746a247a37cdc5d9
+
+        // 2^36 * 8 * B
+
+        .quad   0xd531b8bd2b7b9af6
+        .quad   0x5005093537fc5b51
+        .quad   0x232fcf25c593546d
+        .quad   0x20a365142bb40f49
+        .quad   0x6eccd85278d941ed
+        .quad   0x2254ae83d22f7843
+        .quad   0xc522d02e7bbfcdb7
+        .quad   0x681e3351bff0e4e2
+        .quad   0x8b64b59d83034f45
+        .quad   0x2f8b71f21fa20efb
+        .quad   0x69249495ba6550e4
+        .quad   0x539ef98e45d5472b
+
+        // 2^40 * 1 * B
+
+        .quad   0x6e7bb6a1a6205275
+        .quad   0xaa4f21d7413c8e83
+        .quad   0x6f56d155e88f5cb2
+        .quad   0x2de25d4ba6345be1
+        .quad   0xd074d8961cae743f
+        .quad   0xf86d18f5ee1c63ed
+        .quad   0x97bdc55be7f4ed29
+        .quad   0x4cbad279663ab108
+        .quad   0x80d19024a0d71fcd
+        .quad   0xc525c20afb288af8
+        .quad   0xb1a3974b5f3a6419
+        .quad   0x7d7fbcefe2007233
+
+        // 2^40 * 2 * B
+
+        .quad   0xfaef1e6a266b2801
+        .quad   0x866c68c4d5739f16
+        .quad   0xf68a2fbc1b03762c
+        .quad   0x5975435e87b75a8d
+        .quad   0xcd7c5dc5f3c29094
+        .quad   0xc781a29a2a9105ab
+        .quad   0x80c61d36421c3058
+        .quad   0x4f9cd196dcd8d4d7
+        .quad   0x199297d86a7b3768
+        .quad   0xd0d058241ad17a63
+        .quad   0xba029cad5c1c0c17
+        .quad   0x7ccdd084387a0307
+
+        // 2^40 * 3 * B
+
+        .quad   0xdca6422c6d260417
+        .quad   0xae153d50948240bd
+        .quad   0xa9c0c1b4fb68c677
+        .quad   0x428bd0ed61d0cf53
+        .quad   0x9b0c84186760cc93
+        .quad   0xcdae007a1ab32a99
+        .quad   0xa88dec86620bda18
+        .quad   0x3593ca848190ca44
+        .quad   0x9213189a5e849aa7
+        .quad   0xd4d8c33565d8facd
+        .quad   0x8c52545b53fdbbd1
+        .quad   0x27398308da2d63e6
+
+        // 2^40 * 4 * B
+
+        .quad   0x42c38d28435ed413
+        .quad   0xbd50f3603278ccc9
+        .quad   0xbb07ab1a79da03ef
+        .quad   0x269597aebe8c3355
+        .quad   0xb9a10e4c0a702453
+        .quad   0x0fa25866d57d1bde
+        .quad   0xffb9d9b5cd27daf7
+        .quad   0x572c2945492c33fd
+        .quad   0xc77fc745d6cd30be
+        .quad   0xe4dfe8d3e3baaefb
+        .quad   0xa22c8830aa5dda0c
+        .quad   0x7f985498c05bca80
+
+        // 2^40 * 5 * B
+
+        .quad   0x3849ce889f0be117
+        .quad   0x8005ad1b7b54a288
+        .quad   0x3da3c39f23fc921c
+        .quad   0x76c2ec470a31f304
+        .quad   0xd35615520fbf6363
+        .quad   0x08045a45cf4dfba6
+        .quad   0xeec24fbc873fa0c2
+        .quad   0x30f2653cd69b12e7
+        .quad   0x8a08c938aac10c85
+        .quad   0x46179b60db276bcb
+        .quad   0xa920c01e0e6fac70
+        .quad   0x2f1273f1596473da
+
+        // 2^40 * 6 * B
+
+        .quad   0x4739fc7c8ae01e11
+        .quad   0xfd5274904a6aab9f
+        .quad   0x41d98a8287728f2e
+        .quad   0x5d9e572ad85b69f2
+        .quad   0x30488bd755a70bc0
+        .quad   0x06d6b5a4f1d442e7
+        .quad   0xead1a69ebc596162
+        .quad   0x38ac1997edc5f784
+        .quad   0x0666b517a751b13b
+        .quad   0x747d06867e9b858c
+        .quad   0xacacc011454dde49
+        .quad   0x22dfcd9cbfe9e69c
+
+        // 2^40 * 7 * B
+
+        .quad   0x8ddbd2e0c30d0cd9
+        .quad   0xad8e665facbb4333
+        .quad   0x8f6b258c322a961f
+        .quad   0x6b2916c05448c1c7
+        .quad   0x56ec59b4103be0a1
+        .quad   0x2ee3baecd259f969
+        .quad   0x797cb29413f5cd32
+        .quad   0x0fe9877824cde472
+        .quad   0x7edb34d10aba913b
+        .quad   0x4ea3cd822e6dac0e
+        .quad   0x66083dff6578f815
+        .quad   0x4c303f307ff00a17
+
+        // 2^40 * 8 * B
+
+        .quad   0xd30a3bd617b28c85
+        .quad   0xc5d377b739773bea
+        .quad   0xc6c6e78c1e6a5cbf
+        .quad   0x0d61b8f78b2ab7c4
+        .quad   0x29fc03580dd94500
+        .quad   0xecd27aa46fbbec93
+        .quad   0x130a155fc2e2a7f8
+        .quad   0x416b151ab706a1d5
+        .quad   0x56a8d7efe9c136b0
+        .quad   0xbd07e5cd58e44b20
+        .quad   0xafe62fda1b57e0ab
+        .quad   0x191a2af74277e8d2
+
+        // 2^44 * 1 * B
+
+        .quad   0xd550095bab6f4985
+        .quad   0x04f4cd5b4fbfaf1a
+        .quad   0x9d8e2ed12a0c7540
+        .quad   0x2bc24e04b2212286
+        .quad   0x09d4b60b2fe09a14
+        .quad   0xc384f0afdbb1747e
+        .quad   0x58e2ea8978b5fd6e
+        .quad   0x519ef577b5e09b0a
+        .quad   0x1863d7d91124cca9
+        .quad   0x7ac08145b88a708e
+        .quad   0x2bcd7309857031f5
+        .quad   0x62337a6e8ab8fae5
+
+        // 2^44 * 2 * B
+
+        .quad   0x4bcef17f06ffca16
+        .quad   0xde06e1db692ae16a
+        .quad   0x0753702d614f42b0
+        .quad   0x5f6041b45b9212d0
+        .quad   0xd1ab324e1b3a1273
+        .quad   0x18947cf181055340
+        .quad   0x3b5d9567a98c196e
+        .quad   0x7fa00425802e1e68
+        .quad   0x7d531574028c2705
+        .quad   0x80317d69db0d75fe
+        .quad   0x30fface8ef8c8ddd
+        .quad   0x7e9de97bb6c3e998
+
+        // 2^44 * 3 * B
+
+        .quad   0x1558967b9e6585a3
+        .quad   0x97c99ce098e98b92
+        .quad   0x10af149b6eb3adad
+        .quad   0x42181fe8f4d38cfa
+        .quad   0xf004be62a24d40dd
+        .quad   0xba0659910452d41f
+        .quad   0x81c45ee162a44234
+        .quad   0x4cb829d8a22266ef
+        .quad   0x1dbcaa8407b86681
+        .quad   0x081f001e8b26753b
+        .quad   0x3cd7ce6a84048e81
+        .quad   0x78af11633f25f22c
+
+        // 2^44 * 4 * B
+
+        .quad   0x8416ebd40b50babc
+        .quad   0x1508722628208bee
+        .quad   0xa3148fafb9c1c36d
+        .quad   0x0d07daacd32d7d5d
+        .quad   0x3241c00e7d65318c
+        .quad   0xe6bee5dcd0e86de7
+        .quad   0x118b2dc2fbc08c26
+        .quad   0x680d04a7fc603dc3
+        .quad   0xf9c2414a695aa3eb
+        .quad   0xdaa42c4c05a68f21
+        .quad   0x7c6c23987f93963e
+        .quad   0x210e8cd30c3954e3
+
+        // 2^44 * 5 * B
+
+        .quad   0xac4201f210a71c06
+        .quad   0x6a65e0aef3bfb021
+        .quad   0xbc42c35c393632f7
+        .quad   0x56ea8db1865f0742
+        .quad   0x2b50f16137fe6c26
+        .quad   0xe102bcd856e404d8
+        .quad   0x12b0f1414c561f6b
+        .quad   0x51b17bc8d028ec91
+        .quad   0xfff5fb4bcf535119
+        .quad   0xf4989d79df1108a0
+        .quad   0xbdfcea659a3ba325
+        .quad   0x18a11f1174d1a6f2
+
+        // 2^44 * 6 * B
+
+        .quad   0x407375ab3f6bba29
+        .quad   0x9ec3b6d8991e482e
+        .quad   0x99c80e82e55f92e9
+        .quad   0x307c13b6fb0c0ae1
+        .quad   0xfbd63cdad27a5f2c
+        .quad   0xf00fc4bc8aa106d7
+        .quad   0x53fb5c1a8e64a430
+        .quad   0x04eaabe50c1a2e85
+        .quad   0x24751021cb8ab5e7
+        .quad   0xfc2344495c5010eb
+        .quad   0x5f1e717b4e5610a1
+        .quad   0x44da5f18c2710cd5
+
+        // 2^44 * 7 * B
+
+        .quad   0x033cc55ff1b82eb5
+        .quad   0xb15ae36d411cae52
+        .quad   0xba40b6198ffbacd3
+        .quad   0x768edce1532e861f
+        .quad   0x9156fe6b89d8eacc
+        .quad   0xe6b79451e23126a1
+        .quad   0xbd7463d93944eb4e
+        .quad   0x726373f6767203ae
+        .quad   0xe305ca72eb7ef68a
+        .quad   0x662cf31f70eadb23
+        .quad   0x18f026fdb4c45b68
+        .quad   0x513b5384b5d2ecbd
+
+        // 2^44 * 8 * B
+
+        .quad   0x46d46280c729989e
+        .quad   0x4b93fbd05368a5dd
+        .quad   0x63df3f81d1765a89
+        .quad   0x34cebd64b9a0a223
+        .quad   0x5e2702878af34ceb
+        .quad   0x900b0409b946d6ae
+        .quad   0x6512ebf7dabd8512
+        .quad   0x61d9b76988258f81
+        .quad   0xa6c5a71349b7d94b
+        .quad   0xa3f3d15823eb9446
+        .quad   0x0416fbd277484834
+        .quad   0x69d45e6f2c70812f
+
+        // 2^48 * 1 * B
+
+        .quad   0xce16f74bc53c1431
+        .quad   0x2b9725ce2072edde
+        .quad   0xb8b9c36fb5b23ee7
+        .quad   0x7e2e0e450b5cc908
+        .quad   0x9fe62b434f460efb
+        .quad   0xded303d4a63607d6
+        .quad   0xf052210eb7a0da24
+        .quad   0x237e7dbe00545b93
+        .quad   0x013575ed6701b430
+        .quad   0x231094e69f0bfd10
+        .quad   0x75320f1583e47f22
+        .quad   0x71afa699b11155e3
+
+        // 2^48 * 2 * B
+
+        .quad   0x65ce6f9b3953b61d
+        .quad   0xc65839eaafa141e6
+        .quad   0x0f435ffda9f759fe
+        .quad   0x021142e9c2b1c28e
+        .quad   0xea423c1c473b50d6
+        .quad   0x51e87a1f3b38ef10
+        .quad   0x9b84bf5fb2c9be95
+        .quad   0x00731fbc78f89a1c
+        .quad   0xe430c71848f81880
+        .quad   0xbf960c225ecec119
+        .quad   0xb6dae0836bba15e3
+        .quad   0x4c4d6f3347e15808
+
+        // 2^48 * 3 * B
+
+        .quad   0x18f7eccfc17d1fc9
+        .quad   0x6c75f5a651403c14
+        .quad   0xdbde712bf7ee0cdf
+        .quad   0x193fddaaa7e47a22
+        .quad   0x2f0cddfc988f1970
+        .quad   0x6b916227b0b9f51b
+        .quad   0x6ec7b6c4779176be
+        .quad   0x38bf9500a88f9fa8
+        .quad   0x1fd2c93c37e8876f
+        .quad   0xa2f61e5a18d1462c
+        .quad   0x5080f58239241276
+        .quad   0x6a6fb99ebf0d4969
+
+        // 2^48 * 4 * B
+
+        .quad   0x6a46c1bb560855eb
+        .quad   0x2416bb38f893f09d
+        .quad   0xd71d11378f71acc1
+        .quad   0x75f76914a31896ea
+        .quad   0xeeb122b5b6e423c6
+        .quad   0x939d7010f286ff8e
+        .quad   0x90a92a831dcf5d8c
+        .quad   0x136fda9f42c5eb10
+        .quad   0xf94cdfb1a305bdd1
+        .quad   0x0f364b9d9ff82c08
+        .quad   0x2a87d8a5c3bb588a
+        .quad   0x022183510be8dcba
+
+        // 2^48 * 5 * B
+
+        .quad   0x4af766385ead2d14
+        .quad   0xa08ed880ca7c5830
+        .quad   0x0d13a6e610211e3d
+        .quad   0x6a071ce17b806c03
+        .quad   0x9d5a710143307a7f
+        .quad   0xb063de9ec47da45f
+        .quad   0x22bbfe52be927ad3
+        .quad   0x1387c441fd40426c
+        .quad   0xb5d3c3d187978af8
+        .quad   0x722b5a3d7f0e4413
+        .quad   0x0d7b4848bb477ca0
+        .quad   0x3171b26aaf1edc92
+
+        // 2^48 * 6 * B
+
+        .quad   0xa92f319097564ca8
+        .quad   0xff7bb84c2275e119
+        .quad   0x4f55fe37a4875150
+        .quad   0x221fd4873cf0835a
+        .quad   0xa60db7d8b28a47d1
+        .quad   0xa6bf14d61770a4f1
+        .quad   0xd4a1f89353ddbd58
+        .quad   0x6c514a63344243e9
+        .quad   0x2322204f3a156341
+        .quad   0xfb73e0e9ba0a032d
+        .quad   0xfce0dd4c410f030e
+        .quad   0x48daa596fb924aaa
+
+        // 2^48 * 7 * B
+
+        .quad   0x6eca8e665ca59cc7
+        .quad   0xa847254b2e38aca0
+        .quad   0x31afc708d21e17ce
+        .quad   0x676dd6fccad84af7
+        .quad   0x14f61d5dc84c9793
+        .quad   0x9941f9e3ef418206
+        .quad   0xcdf5b88f346277ac
+        .quad   0x58c837fa0e8a79a9
+        .quad   0x0cf9688596fc9058
+        .quad   0x1ddcbbf37b56a01b
+        .quad   0xdcc2e77d4935d66a
+        .quad   0x1c4f73f2c6a57f0a
+
+        // 2^48 * 8 * B
+
+        .quad   0x0e7a4fbd305fa0bb
+        .quad   0x829d4ce054c663ad
+        .quad   0xf421c3832fe33848
+        .quad   0x795ac80d1bf64c42
+        .quad   0xb36e706efc7c3484
+        .quad   0x73dfc9b4c3c1cf61
+        .quad   0xeb1d79c9781cc7e5
+        .quad   0x70459adb7daf675c
+        .quad   0x1b91db4991b42bb3
+        .quad   0x572696234b02dcca
+        .quad   0x9fdf9ee51f8c78dc
+        .quad   0x5fe162848ce21fd3
+
+        // 2^52 * 1 * B
+
+        .quad   0xe2790aae4d077c41
+        .quad   0x8b938270db7469a3
+        .quad   0x6eb632dc8abd16a2
+        .quad   0x720814ecaa064b72
+        .quad   0x315c29c795115389
+        .quad   0xd7e0e507862f74ce
+        .quad   0x0c4a762185927432
+        .quad   0x72de6c984a25a1e4
+        .quad   0xae9ab553bf6aa310
+        .quad   0x050a50a9806d6e1b
+        .quad   0x92bb7403adff5139
+        .quad   0x0394d27645be618b
+
+        // 2^52 * 2 * B
+
+        .quad   0x4d572251857eedf4
+        .quad   0xe3724edde19e93c5
+        .quad   0x8a71420e0b797035
+        .quad   0x3b3c833687abe743
+        .quad   0xf5396425b23545a4
+        .quad   0x15a7a27e98fbb296
+        .quad   0xab6c52bc636fdd86
+        .quad   0x79d995a8419334ee
+        .quad   0xcd8a8ea61195dd75
+        .quad   0xa504d8a81dd9a82f
+        .quad   0x540dca81a35879b6
+        .quad   0x60dd16a379c86a8a
+
+        // 2^52 * 3 * B
+
+        .quad   0x35a2c8487381e559
+        .quad   0x596ffea6d78082cb
+        .quad   0xcb9771ebdba7b653
+        .quad   0x5a08b5019b4da685
+        .quad   0x3501d6f8153e47b8
+        .quad   0xb7a9675414a2f60c
+        .quad   0x112ee8b6455d9523
+        .quad   0x4e62a3c18112ea8a
+        .quad   0xc8d4ac04516ab786
+        .quad   0x595af3215295b23d
+        .quad   0xd6edd234db0230c1
+        .quad   0x0929efe8825b41cc
+
+        // 2^52 * 4 * B
+
+        .quad   0x5f0601d1cbd0f2d3
+        .quad   0x736e412f6132bb7f
+        .quad   0x83604432238dde87
+        .quad   0x1e3a5272f5c0753c
+        .quad   0x8b3172b7ad56651d
+        .quad   0x01581b7a3fabd717
+        .quad   0x2dc94df6424df6e4
+        .quad   0x30376e5d2c29284f
+        .quad   0xd2918da78159a59c
+        .quad   0x6bdc1cd93f0713f3
+        .quad   0x565f7a934acd6590
+        .quad   0x53daacec4cb4c128
+
+        // 2^52 * 5 * B
+
+        .quad   0x4ca73bd79cc8a7d6
+        .quad   0x4d4a738f47e9a9b2
+        .quad   0xf4cbf12942f5fe00
+        .quad   0x01a13ff9bdbf0752
+        .quad   0x99852bc3852cfdb0
+        .quad   0x2cc12e9559d6ed0b
+        .quad   0x70f9e2bf9b5ac27b
+        .quad   0x4f3b8c117959ae99
+        .quad   0x55b6c9c82ff26412
+        .quad   0x1ac4a8c91fb667a8
+        .quad   0xd527bfcfeb778bf2
+        .quad   0x303337da7012a3be
+
+        // 2^52 * 6 * B
+
+        .quad   0x955422228c1c9d7c
+        .quad   0x01fac1371a9b340f
+        .quad   0x7e8d9177925b48d7
+        .quad   0x53f8ad5661b3e31b
+        .quad   0x976d3ccbfad2fdd1
+        .quad   0xcb88839737a640a8
+        .quad   0x2ff00c1d6734cb25
+        .quad   0x269ff4dc789c2d2b
+        .quad   0x0c003fbdc08d678d
+        .quad   0x4d982fa37ead2b17
+        .quad   0xc07e6bcdb2e582f1
+        .quad   0x296c7291df412a44
+
+        // 2^52 * 7 * B
+
+        .quad   0x7903de2b33daf397
+        .quad   0xd0ff0619c9a624b3
+        .quad   0x8a1d252b555b3e18
+        .quad   0x2b6d581c52e0b7c0
+        .quad   0xdfb23205dab8b59e
+        .quad   0x465aeaa0c8092250
+        .quad   0xd133c1189a725d18
+        .quad   0x2327370261f117d1
+        .quad   0x3d0543d3623e7986
+        .quad   0x679414c2c278a354
+        .quad   0xae43f0cc726196f6
+        .quad   0x7836c41f8245eaba
+
+        // 2^52 * 8 * B
+
+        .quad   0xe7a254db49e95a81
+        .quad   0x5192d5d008b0ad73
+        .quad   0x4d20e5b1d00afc07
+        .quad   0x5d55f8012cf25f38
+        .quad   0xca651e848011937c
+        .quad   0xc6b0c46e6ef41a28
+        .quad   0xb7021ba75f3f8d52
+        .quad   0x119dff99ead7b9fd
+        .quad   0x43eadfcbf4b31d4d
+        .quad   0xc6503f7411148892
+        .quad   0xfeee68c5060d3b17
+        .quad   0x329293b3dd4a0ac8
+
+        // 2^56 * 1 * B
+
+        .quad   0x4e59214fe194961a
+        .quad   0x49be7dc70d71cd4f
+        .quad   0x9300cfd23b50f22d
+        .quad   0x4789d446fc917232
+        .quad   0x2879852d5d7cb208
+        .quad   0xb8dedd70687df2e7
+        .quad   0xdc0bffab21687891
+        .quad   0x2b44c043677daa35
+        .quad   0x1a1c87ab074eb78e
+        .quad   0xfac6d18e99daf467
+        .quad   0x3eacbbcd484f9067
+        .quad   0x60c52eef2bb9a4e4
+
+        // 2^56 * 2 * B
+
+        .quad   0x0b5d89bc3bfd8bf1
+        .quad   0xb06b9237c9f3551a
+        .quad   0x0e4c16b0d53028f5
+        .quad   0x10bc9c312ccfcaab
+        .quad   0x702bc5c27cae6d11
+        .quad   0x44c7699b54a48cab
+        .quad   0xefbc4056ba492eb2
+        .quad   0x70d77248d9b6676d
+        .quad   0xaa8ae84b3ec2a05b
+        .quad   0x98699ef4ed1781e0
+        .quad   0x794513e4708e85d1
+        .quad   0x63755bd3a976f413
+
+        // 2^56 * 3 * B
+
+        .quad   0xb55fa03e2ad10853
+        .quad   0x356f75909ee63569
+        .quad   0x9ff9f1fdbe69b890
+        .quad   0x0d8cc1c48bc16f84
+        .quad   0x3dc7101897f1acb7
+        .quad   0x5dda7d5ec165bbd8
+        .quad   0x508e5b9c0fa1020f
+        .quad   0x2763751737c52a56
+        .quad   0x029402d36eb419a9
+        .quad   0xf0b44e7e77b460a5
+        .quad   0xcfa86230d43c4956
+        .quad   0x70c2dd8a7ad166e7
+
+        // 2^56 * 4 * B
+
+        .quad   0x656194509f6fec0e
+        .quad   0xee2e7ea946c6518d
+        .quad   0x9733c1f367e09b5c
+        .quad   0x2e0fac6363948495
+        .quad   0x91d4967db8ed7e13
+        .quad   0x74252f0ad776817a
+        .quad   0xe40982e00d852564
+        .quad   0x32b8613816a53ce5
+        .quad   0x79e7f7bee448cd64
+        .quad   0x6ac83a67087886d0
+        .quad   0xf89fd4d9a0e4db2e
+        .quad   0x4179215c735a4f41
+
+        // 2^56 * 5 * B
+
+        .quad   0x8c7094e7d7dced2a
+        .quad   0x97fb8ac347d39c70
+        .quad   0xe13be033a906d902
+        .quad   0x700344a30cd99d76
+        .quad   0xe4ae33b9286bcd34
+        .quad   0xb7ef7eb6559dd6dc
+        .quad   0x278b141fb3d38e1f
+        .quad   0x31fa85662241c286
+        .quad   0xaf826c422e3622f4
+        .quad   0xc12029879833502d
+        .quad   0x9bc1b7e12b389123
+        .quad   0x24bb2312a9952489
+
+        // 2^56 * 6 * B
+
+        .quad   0xb1a8ed1732de67c3
+        .quad   0x3cb49418461b4948
+        .quad   0x8ebd434376cfbcd2
+        .quad   0x0fee3e871e188008
+        .quad   0x41f80c2af5f85c6b
+        .quad   0x687284c304fa6794
+        .quad   0x8945df99a3ba1bad
+        .quad   0x0d1d2af9ffeb5d16
+        .quad   0xa9da8aa132621edf
+        .quad   0x30b822a159226579
+        .quad   0x4004197ba79ac193
+        .quad   0x16acd79718531d76
+
+        // 2^56 * 7 * B
+
+        .quad   0x72df72af2d9b1d3d
+        .quad   0x63462a36a432245a
+        .quad   0x3ecea07916b39637
+        .quad   0x123e0ef6b9302309
+        .quad   0xc959c6c57887b6ad
+        .quad   0x94e19ead5f90feba
+        .quad   0x16e24e62a342f504
+        .quad   0x164ed34b18161700
+        .quad   0x487ed94c192fe69a
+        .quad   0x61ae2cea3a911513
+        .quad   0x877bf6d3b9a4de27
+        .quad   0x78da0fc61073f3eb
+
+        // 2^56 * 8 * B
+
+        .quad   0x5bf15d28e52bc66a
+        .quad   0x2c47e31870f01a8e
+        .quad   0x2419afbc06c28bdd
+        .quad   0x2d25deeb256b173a
+        .quad   0xa29f80f1680c3a94
+        .quad   0x71f77e151ae9e7e6
+        .quad   0x1100f15848017973
+        .quad   0x054aa4b316b38ddd
+        .quad   0xdfc8468d19267cb8
+        .quad   0x0b28789c66e54daf
+        .quad   0x2aeb1d2a666eec17
+        .quad   0x134610a6ab7da760
+
+        // 2^60 * 1 * B
+
+        .quad   0xcaf55ec27c59b23f
+        .quad   0x99aeed3e154d04f2
+        .quad   0x68441d72e14141f4
+        .quad   0x140345133932a0a2
+        .quad   0xd91430e0dc028c3c
+        .quad   0x0eb955a85217c771
+        .quad   0x4b09e1ed2c99a1fa
+        .quad   0x42881af2bd6a743c
+        .quad   0x7bfec69aab5cad3d
+        .quad   0xc23e8cd34cb2cfad
+        .quad   0x685dd14bfb37d6a2
+        .quad   0x0ad6d64415677a18
+
+        // 2^60 * 2 * B
+
+        .quad   0x781a439e417becb5
+        .quad   0x4ac5938cd10e0266
+        .quad   0x5da385110692ac24
+        .quad   0x11b065a2ade31233
+        .quad   0x7914892847927e9f
+        .quad   0x33dad6ef370aa877
+        .quad   0x1f8f24fa11122703
+        .quad   0x5265ac2f2adf9592
+        .quad   0x405fdd309afcb346
+        .quad   0xd9723d4428e63f54
+        .quad   0x94c01df05f65aaae
+        .quad   0x43e4dc3ae14c0809
+
+        // 2^60 * 3 * B
+
+        .quad   0xbc12c7f1a938a517
+        .quad   0x473028ab3180b2e1
+        .quad   0x3f78571efbcd254a
+        .quad   0x74e534426ff6f90f
+        .quad   0xea6f7ac3adc2c6a3
+        .quad   0xd0e928f6e9717c94
+        .quad   0xe2d379ead645eaf5
+        .quad   0x46dd8785c51ffbbe
+        .quad   0x709801be375c8898
+        .quad   0x4b06dab5e3fd8348
+        .quad   0x75880ced27230714
+        .quad   0x2b09468fdd2f4c42
+
+        // 2^60 * 4 * B
+
+        .quad   0x97c749eeb701cb96
+        .quad   0x83f438d4b6a369c3
+        .quad   0x62962b8b9a402cd9
+        .quad   0x6976c7509888df7b
+        .quad   0x5b97946582ffa02a
+        .quad   0xda096a51fea8f549
+        .quad   0xa06351375f77af9b
+        .quad   0x1bcfde61201d1e76
+        .quad   0x4a4a5490246a59a2
+        .quad   0xd63ebddee87fdd90
+        .quad   0xd9437c670d2371fa
+        .quad   0x69e87308d30f8ed6
+
+        // 2^60 * 5 * B
+
+        .quad   0x435a8bb15656beb0
+        .quad   0xf8fac9ba4f4d5bca
+        .quad   0xb9b278c41548c075
+        .quad   0x3eb0ef76e892b622
+        .quad   0x0f80bf028bc80303
+        .quad   0x6aae16b37a18cefb
+        .quad   0xdd47ea47d72cd6a3
+        .quad   0x61943588f4ed39aa
+        .quad   0xd26e5c3e91039f85
+        .quad   0xc0e9e77df6f33aa9
+        .quad   0xe8968c5570066a93
+        .quad   0x3c34d1881faaaddd
+
+        // 2^60 * 6 * B
+
+        .quad   0x3f9d2b5ea09f9ec0
+        .quad   0x1dab3b6fb623a890
+        .quad   0xa09ba3ea72d926c4
+        .quad   0x374193513fd8b36d
+        .quad   0xbd5b0b8f2fffe0d9
+        .quad   0x6aa254103ed24fb9
+        .quad   0x2ac7d7bcb26821c4
+        .quad   0x605b394b60dca36a
+        .quad   0xb4e856e45a9d1ed2
+        .quad   0xefe848766c97a9a2
+        .quad   0xb104cf641e5eee7d
+        .quad   0x2f50b81c88a71c8f
+
+        // 2^60 * 7 * B
+
+        .quad   0x31723c61fc6811bb
+        .quad   0x9cb450486211800f
+        .quad   0x768933d347995753
+        .quad   0x3491a53502752fcd
+        .quad   0x2b552ca0a7da522a
+        .quad   0x3230b336449b0250
+        .quad   0xf2c4c5bca4b99fb9
+        .quad   0x7b2c674958074a22
+        .quad   0xd55165883ed28cdf
+        .quad   0x12d84fd2d362de39
+        .quad   0x0a874ad3e3378e4f
+        .quad   0x000d2b1f7c763e74
+
+        // 2^60 * 8 * B
+
+        .quad   0x3d420811d06d4a67
+        .quad   0xbefc048590e0ffe3
+        .quad   0xf870c6b7bd487bde
+        .quad   0x6e2a7316319afa28
+        .quad   0x9624778c3e94a8ab
+        .quad   0x0ad6f3cee9a78bec
+        .quad   0x948ac7810d743c4f
+        .quad   0x76627935aaecfccc
+        .quad   0x56a8ac24d6d59a9f
+        .quad   0xc8db753e3096f006
+        .quad   0x477f41e68f4c5299
+        .quad   0x588d851cf6c86114
+
+        // 2^64 * 1 * B
+
+        .quad   0x51138ec78df6b0fe
+        .quad   0x5397da89e575f51b
+        .quad   0x09207a1d717af1b9
+        .quad   0x2102fdba2b20d650
+        .quad   0xcd2a65e777d1f515
+        .quad   0x548991878faa60f1
+        .quad   0xb1b73bbcdabc06e5
+        .quad   0x654878cba97cc9fb
+        .quad   0x969ee405055ce6a1
+        .quad   0x36bca7681251ad29
+        .quad   0x3a1af517aa7da415
+        .quad   0x0ad725db29ecb2ba
+
+        // 2^64 * 2 * B
+
+        .quad   0xdc4267b1834e2457
+        .quad   0xb67544b570ce1bc5
+        .quad   0x1af07a0bf7d15ed7
+        .quad   0x4aefcffb71a03650
+        .quad   0xfec7bc0c9b056f85
+        .quad   0x537d5268e7f5ffd7
+        .quad   0x77afc6624312aefa
+        .quad   0x4f675f5302399fd9
+        .quad   0xc32d36360415171e
+        .quad   0xcd2bef118998483b
+        .quad   0x870a6eadd0945110
+        .quad   0x0bccbb72a2a86561
+
+        // 2^64 * 3 * B
+
+        .quad   0x185e962feab1a9c8
+        .quad   0x86e7e63565147dcd
+        .quad   0xb092e031bb5b6df2
+        .quad   0x4024f0ab59d6b73e
+        .quad   0x186d5e4c50fe1296
+        .quad   0xe0397b82fee89f7e
+        .quad   0x3bc7f6c5507031b0
+        .quad   0x6678fd69108f37c2
+        .quad   0x1586fa31636863c2
+        .quad   0x07f68c48572d33f2
+        .quad   0x4f73cc9f789eaefc
+        .quad   0x2d42e2108ead4701
+
+        // 2^64 * 4 * B
+
+        .quad   0x97f5131594dfd29b
+        .quad   0x6155985d313f4c6a
+        .quad   0xeba13f0708455010
+        .quad   0x676b2608b8d2d322
+        .quad   0x21717b0d0f537593
+        .quad   0x914e690b131e064c
+        .quad   0x1bb687ae752ae09f
+        .quad   0x420bf3a79b423c6e
+        .quad   0x8138ba651c5b2b47
+        .quad   0x8671b6ec311b1b80
+        .quad   0x7bff0cb1bc3135b0
+        .quad   0x745d2ffa9c0cf1e0
+
+        // 2^64 * 5 * B
+
+        .quad   0xbf525a1e2bc9c8bd
+        .quad   0xea5b260826479d81
+        .quad   0xd511c70edf0155db
+        .quad   0x1ae23ceb960cf5d0
+        .quad   0x6036df5721d34e6a
+        .quad   0xb1db8827997bb3d0
+        .quad   0xd3c209c3c8756afa
+        .quad   0x06e15be54c1dc839
+        .quad   0x5b725d871932994a
+        .quad   0x32351cb5ceb1dab0
+        .quad   0x7dc41549dab7ca05
+        .quad   0x58ded861278ec1f7
+
+        // 2^64 * 6 * B
+
+        .quad   0xd8173793f266c55c
+        .quad   0xc8c976c5cc454e49
+        .quad   0x5ce382f8bc26c3a8
+        .quad   0x2ff39de85485f6f9
+        .quad   0x2dfb5ba8b6c2c9a8
+        .quad   0x48eeef8ef52c598c
+        .quad   0x33809107f12d1573
+        .quad   0x08ba696b531d5bd8
+        .quad   0x77ed3eeec3efc57a
+        .quad   0x04e05517d4ff4811
+        .quad   0xea3d7a3ff1a671cb
+        .quad   0x120633b4947cfe54
+
+        // 2^64 * 7 * B
+
+        .quad   0x0b94987891610042
+        .quad   0x4ee7b13cecebfae8
+        .quad   0x70be739594f0a4c0
+        .quad   0x35d30a99b4d59185
+        .quad   0x82bd31474912100a
+        .quad   0xde237b6d7e6fbe06
+        .quad   0xe11e761911ea79c6
+        .quad   0x07433be3cb393bde
+        .quad   0xff7944c05ce997f4
+        .quad   0x575d3de4b05c51a3
+        .quad   0x583381fd5a76847c
+        .quad   0x2d873ede7af6da9f
+
+        // 2^64 * 8 * B
+
+        .quad   0x157a316443373409
+        .quad   0xfab8b7eef4aa81d9
+        .quad   0xb093fee6f5a64806
+        .quad   0x2e773654707fa7b6
+        .quad   0xaa6202e14e5df981
+        .quad   0xa20d59175015e1f5
+        .quad   0x18a275d3bae21d6c
+        .quad   0x0543618a01600253
+        .quad   0x0deabdf4974c23c1
+        .quad   0xaa6f0a259dce4693
+        .quad   0x04202cb8a29aba2c
+        .quad   0x4b1443362d07960d
+
+        // 2^68 * 1 * B
+
+        .quad   0x47b837f753242cec
+        .quad   0x256dc48cc04212f2
+        .quad   0xe222fbfbe1d928c5
+        .quad   0x48ea295bad8a2c07
+        .quad   0x299b1c3f57c5715e
+        .quad   0x96cb929e6b686d90
+        .quad   0x3004806447235ab3
+        .quad   0x2c435c24a44d9fe1
+        .quad   0x0607c97c80f8833f
+        .quad   0x0e851578ca25ec5b
+        .quad   0x54f7450b161ebb6f
+        .quad   0x7bcb4792a0def80e
+
+        // 2^68 * 2 * B
+
+        .quad   0x8487e3d02bc73659
+        .quad   0x4baf8445059979df
+        .quad   0xd17c975adcad6fbf
+        .quad   0x57369f0bdefc96b6
+        .quad   0x1cecd0a0045224c2
+        .quad   0x757f1b1b69e53952
+        .quad   0x775b7a925289f681
+        .quad   0x1b6cc62016736148
+        .quad   0xf1a9990175638698
+        .quad   0x353dd1beeeaa60d3
+        .quad   0x849471334c9ba488
+        .quad   0x63fa6e6843ade311
+
+        // 2^68 * 3 * B
+
+        .quad   0xd15c20536597c168
+        .quad   0x9f73740098d28789
+        .quad   0x18aee7f13257ba1f
+        .quad   0x3418bfda07346f14
+        .quad   0x2195becdd24b5eb7
+        .quad   0x5e41f18cc0cd44f9
+        .quad   0xdf28074441ca9ede
+        .quad   0x07073b98f35b7d67
+        .quad   0xd03c676c4ce530d4
+        .quad   0x0b64c0473b5df9f4
+        .quad   0x065cef8b19b3a31e
+        .quad   0x3084d661533102c9
+
+        // 2^68 * 4 * B
+
+        .quad   0xe1f6b79ebf8469ad
+        .quad   0x15801004e2663135
+        .quad   0x9a498330af74181b
+        .quad   0x3ba2504f049b673c
+        .quad   0x9a6ce876760321fd
+        .quad   0x7fe2b5109eb63ad8
+        .quad   0x00e7d4ae8ac80592
+        .quad   0x73d86b7abb6f723a
+        .quad   0x0b52b5606dba5ab6
+        .quad   0xa9134f0fbbb1edab
+        .quad   0x30a9520d9b04a635
+        .quad   0x6813b8f37973e5db
+
+        // 2^68 * 5 * B
+
+        .quad   0x9854b054334127c1
+        .quad   0x105d047882fbff25
+        .quad   0xdb49f7f944186f4f
+        .quad   0x1768e838bed0b900
+        .quad   0xf194ca56f3157e29
+        .quad   0x136d35705ef528a5
+        .quad   0xdd4cef778b0599bc
+        .quad   0x7d5472af24f833ed
+        .quad   0xd0ef874daf33da47
+        .quad   0x00d3be5db6e339f9
+        .quad   0x3f2a8a2f9c9ceece
+        .quad   0x5d1aeb792352435a
+
+        // 2^68 * 6 * B
+
+        .quad   0xf59e6bb319cd63ca
+        .quad   0x670c159221d06839
+        .quad   0xb06d565b2150cab6
+        .quad   0x20fb199d104f12a3
+        .quad   0x12c7bfaeb61ba775
+        .quad   0xb84e621fe263bffd
+        .quad   0x0b47a5c35c840dcf
+        .quad   0x7e83be0bccaf8634
+        .quad   0x61943dee6d99c120
+        .quad   0x86101f2e460b9fe0
+        .quad   0x6bb2f1518ee8598d
+        .quad   0x76b76289fcc475cc
+
+        // 2^68 * 7 * B
+
+        .quad   0x791b4cc1756286fa
+        .quad   0xdbced317d74a157c
+        .quad   0x7e732421ea72bde6
+        .quad   0x01fe18491131c8e9
+        .quad   0x4245f1a1522ec0b3
+        .quad   0x558785b22a75656d
+        .quad   0x1d485a2548a1b3c0
+        .quad   0x60959eccd58fe09f
+        .quad   0x3ebfeb7ba8ed7a09
+        .quad   0x49fdc2bbe502789c
+        .quad   0x44ebce5d3c119428
+        .quad   0x35e1eb55be947f4a
+
+        // 2^68 * 8 * B
+
+        .quad   0xdbdae701c5738dd3
+        .quad   0xf9c6f635b26f1bee
+        .quad   0x61e96a8042f15ef4
+        .quad   0x3aa1d11faf60a4d8
+        .quad   0x14fd6dfa726ccc74
+        .quad   0x3b084cfe2f53b965
+        .quad   0xf33ae4f552a2c8b4
+        .quad   0x59aab07a0d40166a
+        .quad   0x77bcec4c925eac25
+        .quad   0x1848718460137738
+        .quad   0x5b374337fea9f451
+        .quad   0x1865e78ec8e6aa46
+
+        // 2^72 * 1 * B
+
+        .quad   0xccc4b7c7b66e1f7a
+        .quad   0x44157e25f50c2f7e
+        .quad   0x3ef06dfc713eaf1c
+        .quad   0x582f446752da63f7
+        .quad   0x967c54e91c529ccb
+        .quad   0x30f6269264c635fb
+        .quad   0x2747aff478121965
+        .quad   0x17038418eaf66f5c
+        .quad   0xc6317bd320324ce4
+        .quad   0xa81042e8a4488bc4
+        .quad   0xb21ef18b4e5a1364
+        .quad   0x0c2a1c4bcda28dc9
+
+        // 2^72 * 2 * B
+
+        .quad   0xd24dc7d06f1f0447
+        .quad   0xb2269e3edb87c059
+        .quad   0xd15b0272fbb2d28f
+        .quad   0x7c558bd1c6f64877
+        .quad   0xedc4814869bd6945
+        .quad   0x0d6d907dbe1c8d22
+        .quad   0xc63bd212d55cc5ab
+        .quad   0x5a6a9b30a314dc83
+        .quad   0xd0ec1524d396463d
+        .quad   0x12bb628ac35a24f0
+        .quad   0xa50c3a791cbc5fa4
+        .quad   0x0404a5ca0afbafc3
+
+        // 2^72 * 3 * B
+
+        .quad   0x8c1f40070aa743d6
+        .quad   0xccbad0cb5b265ee8
+        .quad   0x574b046b668fd2de
+        .quad   0x46395bfdcadd9633
+        .quad   0x62bc9e1b2a416fd1
+        .quad   0xb5c6f728e350598b
+        .quad   0x04343fd83d5d6967
+        .quad   0x39527516e7f8ee98
+        .quad   0x117fdb2d1a5d9a9c
+        .quad   0x9c7745bcd1005c2a
+        .quad   0xefd4bef154d56fea
+        .quad   0x76579a29e822d016
+
+        // 2^72 * 4 * B
+
+        .quad   0x45b68e7e49c02a17
+        .quad   0x23cd51a2bca9a37f
+        .quad   0x3ed65f11ec224c1b
+        .quad   0x43a384dc9e05bdb1
+        .quad   0x333cb51352b434f2
+        .quad   0xd832284993de80e1
+        .quad   0xb5512887750d35ce
+        .quad   0x02c514bb2a2777c1
+        .quad   0x684bd5da8bf1b645
+        .quad   0xfb8bd37ef6b54b53
+        .quad   0x313916d7a9b0d253
+        .quad   0x1160920961548059
+
+        // 2^72 * 5 * B
+
+        .quad   0xb44d166929dacfaa
+        .quad   0xda529f4c8413598f
+        .quad   0xe9ef63ca453d5559
+        .quad   0x351e125bc5698e0b
+        .quad   0x7a385616369b4dcd
+        .quad   0x75c02ca7655c3563
+        .quad   0x7dc21bf9d4f18021
+        .quad   0x2f637d7491e6e042
+        .quad   0xd4b49b461af67bbe
+        .quad   0xd603037ac8ab8961
+        .quad   0x71dee19ff9a699fb
+        .quad   0x7f182d06e7ce2a9a
+
+        // 2^72 * 6 * B
+
+        .quad   0x7a7c8e64ab0168ec
+        .quad   0xcb5a4a5515edc543
+        .quad   0x095519d347cd0eda
+        .quad   0x67d4ac8c343e93b0
+        .quad   0x09454b728e217522
+        .quad   0xaa58e8f4d484b8d8
+        .quad   0xd358254d7f46903c
+        .quad   0x44acc043241c5217
+        .quad   0x1c7d6bbb4f7a5777
+        .quad   0x8b35fed4918313e1
+        .quad   0x4adca1c6c96b4684
+        .quad   0x556d1c8312ad71bd
+
+        // 2^72 * 7 * B
+
+        .quad   0x17ef40e30c8d3982
+        .quad   0x31f7073e15a3fa34
+        .quad   0x4f21f3cb0773646e
+        .quad   0x746c6c6d1d824eff
+        .quad   0x81f06756b11be821
+        .quad   0x0faff82310a3f3dd
+        .quad   0xf8b2d0556a99465d
+        .quad   0x097abe38cc8c7f05
+        .quad   0x0c49c9877ea52da4
+        .quad   0x4c4369559bdc1d43
+        .quad   0x022c3809f7ccebd2
+        .quad   0x577e14a34bee84bd
+
+        // 2^72 * 8 * B
+
+        .quad   0xf0e268ac61a73b0a
+        .quad   0xf2fafa103791a5f5
+        .quad   0xc1e13e826b6d00e9
+        .quad   0x60fa7ee96fd78f42
+        .quad   0x94fecebebd4dd72b
+        .quad   0xf46a4fda060f2211
+        .quad   0x124a5977c0c8d1ff
+        .quad   0x705304b8fb009295
+        .quad   0xb63d1d354d296ec6
+        .quad   0xf3c3053e5fad31d8
+        .quad   0x670b958cb4bd42ec
+        .quad   0x21398e0ca16353fd
+
+        // 2^76 * 1 * B
+
+        .quad   0x216ab2ca8da7d2ef
+        .quad   0x366ad9dd99f42827
+        .quad   0xae64b9004fdd3c75
+        .quad   0x403a395b53909e62
+        .quad   0x86c5fc16861b7e9a
+        .quad   0xf6a330476a27c451
+        .quad   0x01667267a1e93597
+        .quad   0x05ffb9cd6082dfeb
+        .quad   0xa617fa9ff53f6139
+        .quad   0x60f2b5e513e66cb6
+        .quad   0xd7a8beefb3448aa4
+        .quad   0x7a2932856f5ea192
+
+        // 2^76 * 2 * B
+
+        .quad   0x0b39d761b02de888
+        .quad   0x5f550e7ed2414e1f
+        .quad   0xa6bfa45822e1a940
+        .quad   0x050a2f7dfd447b99
+        .quad   0xb89c444879639302
+        .quad   0x4ae4f19350c67f2c
+        .quad   0xf0b35da8c81af9c6
+        .quad   0x39d0003546871017
+        .quad   0x437c3b33a650db77
+        .quad   0x6bafe81dbac52bb2
+        .quad   0xfe99402d2db7d318
+        .quad   0x2b5b7eec372ba6ce
+
+        // 2^76 * 3 * B
+
+        .quad   0xb3bc4bbd83f50eef
+        .quad   0x508f0c998c927866
+        .quad   0x43e76587c8b7e66e
+        .quad   0x0f7655a3a47f98d9
+        .quad   0xa694404d613ac8f4
+        .quad   0x500c3c2bfa97e72c
+        .quad   0x874104d21fcec210
+        .quad   0x1b205fb38604a8ee
+        .quad   0x55ecad37d24b133c
+        .quad   0x441e147d6038c90b
+        .quad   0x656683a1d62c6fee
+        .quad   0x0157d5dc87e0ecae
+
+        // 2^76 * 4 * B
+
+        .quad   0xf2a7af510354c13d
+        .quad   0xd7a0b145aa372b60
+        .quad   0x2869b96a05a3d470
+        .quad   0x6528e42d82460173
+        .quad   0x95265514d71eb524
+        .quad   0xe603d8815df14593
+        .quad   0x147cdf410d4de6b7
+        .quad   0x5293b1730437c850
+        .quad   0x23d0e0814bccf226
+        .quad   0x92c745cd8196fb93
+        .quad   0x8b61796c59541e5b
+        .quad   0x40a44df0c021f978
+
+        // 2^76 * 5 * B
+
+        .quad   0xdaa869894f20ea6a
+        .quad   0xea14a3d14c620618
+        .quad   0x6001fccb090bf8be
+        .quad   0x35f4e822947e9cf0
+        .quad   0x86c96e514bc5d095
+        .quad   0xf20d4098fca6804a
+        .quad   0x27363d89c826ea5d
+        .quad   0x39ca36565719cacf
+        .quad   0x97506f2f6f87b75c
+        .quad   0xc624aea0034ae070
+        .quad   0x1ec856e3aad34dd6
+        .quad   0x055b0be0e440e58f
+
+        // 2^76 * 6 * B
+
+        .quad   0x6469a17d89735d12
+        .quad   0xdb6f27d5e662b9f1
+        .quad   0x9fcba3286a395681
+        .quad   0x363b8004d269af25
+        .quad   0x4d12a04b6ea33da2
+        .quad   0x57cf4c15e36126dd
+        .quad   0x90ec9675ee44d967
+        .quad   0x64ca348d2a985aac
+        .quad   0x99588e19e4c4912d
+        .quad   0xefcc3b4e1ca5ce6b
+        .quad   0x4522ea60fa5b98d5
+        .quad   0x7064bbab1de4a819
+
+        // 2^76 * 7 * B
+
+        .quad   0xb919e1515a770641
+        .quad   0xa9a2e2c74e7f8039
+        .quad   0x7527250b3df23109
+        .quad   0x756a7330ac27b78b
+        .quad   0xa290c06142542129
+        .quad   0xf2e2c2aebe8d5b90
+        .quad   0xcf2458db76abfe1b
+        .quad   0x02157ade83d626bf
+        .quad   0x3e46972a1b9a038b
+        .quad   0x2e4ee66a7ee03fb4
+        .quad   0x81a248776edbb4ca
+        .quad   0x1a944ee88ecd0563
+
+        // 2^76 * 8 * B
+
+        .quad   0xd5a91d1151039372
+        .quad   0x2ed377b799ca26de
+        .quad   0xa17202acfd366b6b
+        .quad   0x0730291bd6901995
+        .quad   0xbb40a859182362d6
+        .quad   0xb99f55778a4d1abb
+        .quad   0x8d18b427758559f6
+        .quad   0x26c20fe74d26235a
+        .quad   0x648d1d9fe9cc22f5
+        .quad   0x66bc561928dd577c
+        .quad   0x47d3ed21652439d1
+        .quad   0x49d271acedaf8b49
+
+        // 2^80 * 1 * B
+
+        .quad   0x89f5058a382b33f3
+        .quad   0x5ae2ba0bad48c0b4
+        .quad   0x8f93b503a53db36e
+        .quad   0x5aa3ed9d95a232e6
+        .quad   0x2798aaf9b4b75601
+        .quad   0x5eac72135c8dad72
+        .quad   0xd2ceaa6161b7a023
+        .quad   0x1bbfb284e98f7d4e
+        .quad   0x656777e9c7d96561
+        .quad   0xcb2b125472c78036
+        .quad   0x65053299d9506eee
+        .quad   0x4a07e14e5e8957cc
+
+        // 2^80 * 2 * B
+
+        .quad   0x4ee412cb980df999
+        .quad   0xa315d76f3c6ec771
+        .quad   0xbba5edde925c77fd
+        .quad   0x3f0bac391d313402
+        .quad   0x240b58cdc477a49b
+        .quad   0xfd38dade6447f017
+        .quad   0x19928d32a7c86aad
+        .quad   0x50af7aed84afa081
+        .quad   0x6e4fde0115f65be5
+        .quad   0x29982621216109b2
+        .quad   0x780205810badd6d9
+        .quad   0x1921a316baebd006
+
+        // 2^80 * 3 * B
+
+        .quad   0x89422f7edfb870fc
+        .quad   0x2c296beb4f76b3bd
+        .quad   0x0738f1d436c24df7
+        .quad   0x6458df41e273aeb0
+        .quad   0xd75aad9ad9f3c18b
+        .quad   0x566a0eef60b1c19c
+        .quad   0x3e9a0bac255c0ed9
+        .quad   0x7b049deca062c7f5
+        .quad   0xdccbe37a35444483
+        .quad   0x758879330fedbe93
+        .quad   0x786004c312c5dd87
+        .quad   0x6093dccbc2950e64
+
+        // 2^80 * 4 * B
+
+        .quad   0x1ff39a8585e0706d
+        .quad   0x36d0a5d8b3e73933
+        .quad   0x43b9f2e1718f453b
+        .quad   0x57d1ea084827a97c
+        .quad   0x6bdeeebe6084034b
+        .quad   0x3199c2b6780fb854
+        .quad   0x973376abb62d0695
+        .quad   0x6e3180c98b647d90
+        .quad   0xee7ab6e7a128b071
+        .quad   0xa4c1596d93a88baa
+        .quad   0xf7b4de82b2216130
+        .quad   0x363e999ddd97bd18
+
+        // 2^80 * 5 * B
+
+        .quad   0x96a843c135ee1fc4
+        .quad   0x976eb35508e4c8cf
+        .quad   0xb42f6801b58cd330
+        .quad   0x48ee9b78693a052b
+        .quad   0x2f1848dce24baec6
+        .quad   0x769b7255babcaf60
+        .quad   0x90cb3c6e3cefe931
+        .quad   0x231f979bc6f9b355
+        .quad   0x5c31de4bcc2af3c6
+        .quad   0xb04bb030fe208d1f
+        .quad   0xb78d7009c14fb466
+        .quad   0x079bfa9b08792413
+
+        // 2^80 * 6 * B
+
+        .quad   0xe3903a51da300df4
+        .quad   0x843964233da95ab0
+        .quad   0xed3cf12d0b356480
+        .quad   0x038c77f684817194
+        .quad   0xf3c9ed80a2d54245
+        .quad   0x0aa08b7877f63952
+        .quad   0xd76dac63d1085475
+        .quad   0x1ef4fb159470636b
+        .quad   0x854e5ee65b167bec
+        .quad   0x59590a4296d0cdc2
+        .quad   0x72b2df3498102199
+        .quad   0x575ee92a4a0bff56
+
+        // 2^80 * 7 * B
+
+        .quad   0xd4c080908a182fcf
+        .quad   0x30e170c299489dbd
+        .quad   0x05babd5752f733de
+        .quad   0x43d4e7112cd3fd00
+        .quad   0x5d46bc450aa4d801
+        .quad   0xc3af1227a533b9d8
+        .quad   0x389e3b262b8906c2
+        .quad   0x200a1e7e382f581b
+        .quad   0x518db967eaf93ac5
+        .quad   0x71bc989b056652c0
+        .quad   0xfe2b85d9567197f5
+        .quad   0x050eca52651e4e38
+
+        // 2^80 * 8 * B
+
+        .quad   0xc3431ade453f0c9c
+        .quad   0xe9f5045eff703b9b
+        .quad   0xfcd97ac9ed847b3d
+        .quad   0x4b0ee6c21c58f4c6
+        .quad   0x97ac397660e668ea
+        .quad   0x9b19bbfe153ab497
+        .quad   0x4cb179b534eca79f
+        .quad   0x6151c09fa131ae57
+        .quad   0x3af55c0dfdf05d96
+        .quad   0xdd262ee02ab4ee7a
+        .quad   0x11b2bb8712171709
+        .quad   0x1fef24fa800f030b
+
+        // 2^84 * 1 * B
+
+        .quad   0xb496123a6b6c6609
+        .quad   0xa750fe8580ab5938
+        .quad   0xf471bf39b7c27a5f
+        .quad   0x507903ce77ac193c
+        .quad   0xff91a66a90166220
+        .quad   0xf22552ae5bf1e009
+        .quad   0x7dff85d87f90df7c
+        .quad   0x4f620ffe0c736fb9
+        .quad   0x62f90d65dfde3e34
+        .quad   0xcf28c592b9fa5fad
+        .quad   0x99c86ef9c6164510
+        .quad   0x25d448044a256c84
+
+        // 2^84 * 2 * B
+
+        .quad   0xbd68230ec7e9b16f
+        .quad   0x0eb1b9c1c1c5795d
+        .quad   0x7943c8c495b6b1ff
+        .quad   0x2f9faf620bbacf5e
+        .quad   0x2c7c4415c9022b55
+        .quad   0x56a0d241812eb1fe
+        .quad   0xf02ea1c9d7b65e0d
+        .quad   0x4180512fd5323b26
+        .quad   0xa4ff3e698a48a5db
+        .quad   0xba6a3806bd95403b
+        .quad   0x9f7ce1af47d5b65d
+        .quad   0x15e087e55939d2fb
+
+        // 2^84 * 3 * B
+
+        .quad   0x12207543745c1496
+        .quad   0xdaff3cfdda38610c
+        .quad   0xe4e797272c71c34f
+        .quad   0x39c07b1934bdede9
+        .quad   0x8894186efb963f38
+        .quad   0x48a00e80dc639bd5
+        .quad   0xa4e8092be96c1c99
+        .quad   0x5a097d54ca573661
+        .quad   0x2d45892b17c9e755
+        .quad   0xd033fd7289308df8
+        .quad   0x6c2fe9d9525b8bd9
+        .quad   0x2edbecf1c11cc079
+
+        // 2^84 * 4 * B
+
+        .quad   0x1616a4e3c715a0d2
+        .quad   0x53623cb0f8341d4d
+        .quad   0x96ef5329c7e899cb
+        .quad   0x3d4e8dbba668baa6
+        .quad   0xee0f0fddd087a25f
+        .quad   0x9c7531555c3e34ee
+        .quad   0x660c572e8fab3ab5
+        .quad   0x0854fc44544cd3b2
+        .quad   0x61eba0c555edad19
+        .quad   0x24b533fef0a83de6
+        .quad   0x3b77042883baa5f8
+        .quad   0x678f82b898a47e8d
+
+        // 2^84 * 5 * B
+
+        .quad   0xb1491d0bd6900c54
+        .quad   0x3539722c9d132636
+        .quad   0x4db928920b362bc9
+        .quad   0x4d7cd1fea68b69df
+        .quad   0x1e09d94057775696
+        .quad   0xeed1265c3cd951db
+        .quad   0xfa9dac2b20bce16f
+        .quad   0x0f7f76e0e8d089f4
+        .quad   0x36d9ebc5d485b00c
+        .quad   0xa2596492e4adb365
+        .quad   0xc1659480c2119ccd
+        .quad   0x45306349186e0d5f
+
+        // 2^84 * 6 * B
+
+        .quad   0x94ddd0c1a6cdff1d
+        .quad   0x55f6f115e84213ae
+        .quad   0x6c935f85992fcf6a
+        .quad   0x067ee0f54a37f16f
+        .quad   0x96a414ec2b072491
+        .quad   0x1bb2218127a7b65b
+        .quad   0x6d2849596e8a4af0
+        .quad   0x65f3b08ccd27765f
+        .quad   0xecb29fff199801f7
+        .quad   0x9d361d1fa2a0f72f
+        .quad   0x25f11d2375fd2f49
+        .quad   0x124cefe80fe10fe2
+
+        // 2^84 * 7 * B
+
+        .quad   0x4c126cf9d18df255
+        .quad   0xc1d471e9147a63b6
+        .quad   0x2c6d3c73f3c93b5f
+        .quad   0x6be3a6a2e3ff86a2
+        .quad   0x1518e85b31b16489
+        .quad   0x8faadcb7db710bfb
+        .quad   0x39b0bdf4a14ae239
+        .quad   0x05f4cbea503d20c1
+        .quad   0xce040e9ec04145bc
+        .quad   0xc71ff4e208f6834c
+        .quad   0xbd546e8dab8847a3
+        .quad   0x64666aa0a4d2aba5
+
+        // 2^84 * 8 * B
+
+        .quad   0x6841435a7c06d912
+        .quad   0xca123c21bb3f830b
+        .quad   0xd4b37b27b1cbe278
+        .quad   0x1d753b84c76f5046
+        .quad   0xb0c53bf73337e94c
+        .quad   0x7cb5697e11e14f15
+        .quad   0x4b84abac1930c750
+        .quad   0x28dd4abfe0640468
+        .quad   0x7dc0b64c44cb9f44
+        .quad   0x18a3e1ace3925dbf
+        .quad   0x7a3034862d0457c4
+        .quad   0x4c498bf78a0c892e
+
+        // 2^88 * 1 * B
+
+        .quad   0x37d653fb1aa73196
+        .quad   0x0f9495303fd76418
+        .quad   0xad200b09fb3a17b2
+        .quad   0x544d49292fc8613e
+        .quad   0x22d2aff530976b86
+        .quad   0x8d90b806c2d24604
+        .quad   0xdca1896c4de5bae5
+        .quad   0x28005fe6c8340c17
+        .quad   0x6aefba9f34528688
+        .quad   0x5c1bff9425107da1
+        .quad   0xf75bbbcd66d94b36
+        .quad   0x72e472930f316dfa
+
+        // 2^88 * 2 * B
+
+        .quad   0x2695208c9781084f
+        .quad   0xb1502a0b23450ee1
+        .quad   0xfd9daea603efde02
+        .quad   0x5a9d2e8c2733a34c
+        .quad   0x07f3f635d32a7627
+        .quad   0x7aaa4d865f6566f0
+        .quad   0x3c85e79728d04450
+        .quad   0x1fee7f000fe06438
+        .quad   0x765305da03dbf7e5
+        .quad   0xa4daf2491434cdbd
+        .quad   0x7b4ad5cdd24a88ec
+        .quad   0x00f94051ee040543
+
+        // 2^88 * 3 * B
+
+        .quad   0x8d356b23c3d330b2
+        .quad   0xf21c8b9bb0471b06
+        .quad   0xb36c316c6e42b83c
+        .quad   0x07d79c7e8beab10d
+        .quad   0xd7ef93bb07af9753
+        .quad   0x583ed0cf3db766a7
+        .quad   0xce6998bf6e0b1ec5
+        .quad   0x47b7ffd25dd40452
+        .quad   0x87fbfb9cbc08dd12
+        .quad   0x8a066b3ae1eec29b
+        .quad   0x0d57242bdb1fc1bf
+        .quad   0x1c3520a35ea64bb6
+
+        // 2^88 * 4 * B
+
+        .quad   0x80d253a6bccba34a
+        .quad   0x3e61c3a13838219b
+        .quad   0x90c3b6019882e396
+        .quad   0x1c3d05775d0ee66f
+        .quad   0xcda86f40216bc059
+        .quad   0x1fbb231d12bcd87e
+        .quad   0xb4956a9e17c70990
+        .quad   0x38750c3b66d12e55
+        .quad   0x692ef1409422e51a
+        .quad   0xcbc0c73c2b5df671
+        .quad   0x21014fe7744ce029
+        .quad   0x0621e2c7d330487c
+
+        // 2^88 * 5 * B
+
+        .quad   0xaf9860cc8259838d
+        .quad   0x90ea48c1c69f9adc
+        .quad   0x6526483765581e30
+        .quad   0x0007d6097bd3a5bc
+        .quad   0xb7ae1796b0dbf0f3
+        .quad   0x54dfafb9e17ce196
+        .quad   0x25923071e9aaa3b4
+        .quad   0x5d8e589ca1002e9d
+        .quad   0xc0bf1d950842a94b
+        .quad   0xb2d3c363588f2e3e
+        .quad   0x0a961438bb51e2ef
+        .quad   0x1583d7783c1cbf86
+
+        // 2^88 * 6 * B
+
+        .quad   0xeceea2ef5da27ae1
+        .quad   0x597c3a1455670174
+        .quad   0xc9a62a126609167a
+        .quad   0x252a5f2e81ed8f70
+        .quad   0x90034704cc9d28c7
+        .quad   0x1d1b679ef72cc58f
+        .quad   0x16e12b5fbe5b8726
+        .quad   0x4958064e83c5580a
+        .quad   0x0d2894265066e80d
+        .quad   0xfcc3f785307c8c6b
+        .quad   0x1b53da780c1112fd
+        .quad   0x079c170bd843b388
+
+        // 2^88 * 7 * B
+
+        .quad   0x0506ece464fa6fff
+        .quad   0xbee3431e6205e523
+        .quad   0x3579422451b8ea42
+        .quad   0x6dec05e34ac9fb00
+        .quad   0xcdd6cd50c0d5d056
+        .quad   0x9af7686dbb03573b
+        .quad   0x3ca6723ff3c3ef48
+        .quad   0x6768c0d7317b8acc
+        .quad   0x94b625e5f155c1b3
+        .quad   0x417bf3a7997b7b91
+        .quad   0xc22cbddc6d6b2600
+        .quad   0x51445e14ddcd52f4
+
+        // 2^88 * 8 * B
+
+        .quad   0x57502b4b3b144951
+        .quad   0x8e67ff6b444bbcb3
+        .quad   0xb8bd6927166385db
+        .quad   0x13186f31e39295c8
+        .quad   0x893147ab2bbea455
+        .quad   0x8c53a24f92079129
+        .quad   0x4b49f948be30f7a7
+        .quad   0x12e990086e4fd43d
+        .quad   0xf10c96b37fdfbb2e
+        .quad   0x9f9a935e121ceaf9
+        .quad   0xdf1136c43a5b983f
+        .quad   0x77b2e3f05d3e99af
+
+        // 2^92 * 1 * B
+
+        .quad   0xfd0d75879cf12657
+        .quad   0xe82fef94e53a0e29
+        .quad   0xcc34a7f05bbb4be7
+        .quad   0x0b251172a50c38a2
+        .quad   0x9532f48fcc5cd29b
+        .quad   0x2ba851bea3ce3671
+        .quad   0x32dacaa051122941
+        .quad   0x478d99d9350004f2
+        .quad   0x1d5ad94890bb02c0
+        .quad   0x50e208b10ec25115
+        .quad   0xa26a22894ef21702
+        .quad   0x4dc923343b524805
+
+        // 2^92 * 2 * B
+
+        .quad   0xe3828c400f8086b6
+        .quad   0x3f77e6f7979f0dc8
+        .quad   0x7ef6de304df42cb4
+        .quad   0x5265797cb6abd784
+        .quad   0x3ad3e3ebf36c4975
+        .quad   0xd75d25a537862125
+        .quad   0xe873943da025a516
+        .quad   0x6bbc7cb4c411c847
+        .quad   0x3c6f9cd1d4a50d56
+        .quad   0xb6244077c6feab7e
+        .quad   0x6ff9bf483580972e
+        .quad   0x00375883b332acfb
+
+        // 2^92 * 3 * B
+
+        .quad   0x0001b2cd28cb0940
+        .quad   0x63fb51a06f1c24c9
+        .quad   0xb5ad8691dcd5ca31
+        .quad   0x67238dbd8c450660
+        .quad   0xc98bec856c75c99c
+        .quad   0xe44184c000e33cf4
+        .quad   0x0a676b9bba907634
+        .quad   0x669e2cb571f379d7
+        .quad   0xcb116b73a49bd308
+        .quad   0x025aad6b2392729e
+        .quad   0xb4793efa3f55d9b1
+        .quad   0x72a1056140678bb9
+
+        // 2^92 * 4 * B
+
+        .quad   0xa2b6812b1cc9249d
+        .quad   0x62866eee21211f58
+        .quad   0x2cb5c5b85df10ece
+        .quad   0x03a6b259e263ae00
+        .quad   0x0d8d2909e2e505b6
+        .quad   0x98ca78abc0291230
+        .quad   0x77ef5569a9b12327
+        .quad   0x7c77897b81439b47
+        .quad   0xf1c1b5e2de331cb5
+        .quad   0x5a9f5d8e15fca420
+        .quad   0x9fa438f17bd932b1
+        .quad   0x2a381bf01c6146e7
+
+        // 2^92 * 5 * B
+
+        .quad   0xac9b9879cfc811c1
+        .quad   0x8b7d29813756e567
+        .quad   0x50da4e607c70edfc
+        .quad   0x5dbca62f884400b6
+        .quad   0xf7c0be32b534166f
+        .quad   0x27e6ca6419cf70d4
+        .quad   0x934df7d7a957a759
+        .quad   0x5701461dabdec2aa
+        .quad   0x2c6747402c915c25
+        .quad   0x1bdcd1a80b0d340a
+        .quad   0x5e5601bd07b43f5f
+        .quad   0x2555b4e05539a242
+
+        // 2^92 * 6 * B
+
+        .quad   0x6fc09f5266ddd216
+        .quad   0xdce560a7c8e37048
+        .quad   0xec65939da2df62fd
+        .quad   0x7a869ae7e52ed192
+        .quad   0x78409b1d87e463d4
+        .quad   0xad4da95acdfb639d
+        .quad   0xec28773755259b9c
+        .quad   0x69c806e9c31230ab
+        .quad   0x7b48f57414bb3f22
+        .quad   0x68c7cee4aedccc88
+        .quad   0xed2f936179ed80be
+        .quad   0x25d70b885f77bc4b
+
+        // 2^92 * 7 * B
+
+        .quad   0x4151c3d9762bf4de
+        .quad   0x083f435f2745d82b
+        .quad   0x29775a2e0d23ddd5
+        .quad   0x138e3a6269a5db24
+        .quad   0x98459d29bb1ae4d4
+        .quad   0x56b9c4c739f954ec
+        .quad   0x832743f6c29b4b3e
+        .quad   0x21ea8e2798b6878a
+        .quad   0x87bef4b46a5a7b9c
+        .quad   0xd2299d1b5fc1d062
+        .quad   0x82409818dd321648
+        .quad   0x5c5abeb1e5a2e03d
+
+        // 2^92 * 8 * B
+
+        .quad   0x14722af4b73c2ddb
+        .quad   0xbc470c5f5a05060d
+        .quad   0x00943eac2581b02e
+        .quad   0x0e434b3b1f499c8f
+        .quad   0x02cde6de1306a233
+        .quad   0x7b5a52a2116f8ec7
+        .quad   0xe1c681f4c1163b5b
+        .quad   0x241d350660d32643
+        .quad   0x6be4404d0ebc52c7
+        .quad   0xae46233bb1a791f5
+        .quad   0x2aec170ed25db42b
+        .quad   0x1d8dfd966645d694
+
+        // 2^96 * 1 * B
+
+        .quad   0x296fa9c59c2ec4de
+        .quad   0xbc8b61bf4f84f3cb
+        .quad   0x1c7706d917a8f908
+        .quad   0x63b795fc7ad3255d
+        .quad   0xd598639c12ddb0a4
+        .quad   0xa5d19f30c024866b
+        .quad   0xd17c2f0358fce460
+        .quad   0x07a195152e095e8a
+        .quad   0xa8368f02389e5fc8
+        .quad   0x90433b02cf8de43b
+        .quad   0xafa1fd5dc5412643
+        .quad   0x3e8fe83d032f0137
+
+        // 2^96 * 2 * B
+
+        .quad   0x2f8b15b90570a294
+        .quad   0x94f2427067084549
+        .quad   0xde1c5ae161bbfd84
+        .quad   0x75ba3b797fac4007
+        .quad   0x08704c8de8efd13c
+        .quad   0xdfc51a8e33e03731
+        .quad   0xa59d5da51260cde3
+        .quad   0x22d60899a6258c86
+        .quad   0x6239dbc070cdd196
+        .quad   0x60fe8a8b6c7d8a9a
+        .quad   0xb38847bceb401260
+        .quad   0x0904d07b87779e5e
+
+        // 2^96 * 3 * B
+
+        .quad   0xb4ce1fd4ddba919c
+        .quad   0xcf31db3ec74c8daa
+        .quad   0x2c63cc63ad86cc51
+        .quad   0x43e2143fbc1dde07
+        .quad   0xf4322d6648f940b9
+        .quad   0x06952f0cbd2d0c39
+        .quad   0x167697ada081f931
+        .quad   0x6240aacebaf72a6c
+        .quad   0xf834749c5ba295a0
+        .quad   0xd6947c5bca37d25a
+        .quad   0x66f13ba7e7c9316a
+        .quad   0x56bdaf238db40cac
+
+        // 2^96 * 4 * B
+
+        .quad   0x362ab9e3f53533eb
+        .quad   0x338568d56eb93d40
+        .quad   0x9e0e14521d5a5572
+        .quad   0x1d24a86d83741318
+        .quad   0x1310d36cc19d3bb2
+        .quad   0x062a6bb7622386b9
+        .quad   0x7c9b8591d7a14f5c
+        .quad   0x03aa31507e1e5754
+        .quad   0xf4ec7648ffd4ce1f
+        .quad   0xe045eaf054ac8c1c
+        .quad   0x88d225821d09357c
+        .quad   0x43b261dc9aeb4859
+
+        // 2^96 * 5 * B
+
+        .quad   0xe55b1e1988bb79bb
+        .quad   0xa09ed07dc17a359d
+        .quad   0xb02c2ee2603dea33
+        .quad   0x326055cf5b276bc2
+        .quad   0x19513d8b6c951364
+        .quad   0x94fe7126000bf47b
+        .quad   0x028d10ddd54f9567
+        .quad   0x02b4d5e242940964
+        .quad   0xb4a155cb28d18df2
+        .quad   0xeacc4646186ce508
+        .quad   0xc49cf4936c824389
+        .quad   0x27a6c809ae5d3410
+
+        // 2^96 * 6 * B
+
+        .quad   0x8ba6ebcd1f0db188
+        .quad   0x37d3d73a675a5be8
+        .quad   0xf22edfa315f5585a
+        .quad   0x2cb67174ff60a17e
+        .quad   0xcd2c270ac43d6954
+        .quad   0xdd4a3e576a66cab2
+        .quad   0x79fa592469d7036c
+        .quad   0x221503603d8c2599
+        .quad   0x59eecdf9390be1d0
+        .quad   0xa9422044728ce3f1
+        .quad   0x82891c667a94f0f4
+        .quad   0x7b1df4b73890f436
+
+        // 2^96 * 7 * B
+
+        .quad   0xe492f2e0b3b2a224
+        .quad   0x7c6c9e062b551160
+        .quad   0x15eb8fe20d7f7b0e
+        .quad   0x61fcef2658fc5992
+        .quad   0x5f2e221807f8f58c
+        .quad   0xe3555c9fd49409d4
+        .quad   0xb2aaa88d1fb6a630
+        .quad   0x68698245d352e03d
+        .quad   0xdbb15d852a18187a
+        .quad   0xf3e4aad386ddacd7
+        .quad   0x44bae2810ff6c482
+        .quad   0x46cf4c473daf01cf
+
+        // 2^96 * 8 * B
+
+        .quad   0x426525ed9ec4e5f9
+        .quad   0x0e5eda0116903303
+        .quad   0x72b1a7f2cbe5cadc
+        .quad   0x29387bcd14eb5f40
+        .quad   0x213c6ea7f1498140
+        .quad   0x7c1e7ef8392b4854
+        .quad   0x2488c38c5629ceba
+        .quad   0x1065aae50d8cc5bb
+        .quad   0x1c2c4525df200d57
+        .quad   0x5c3b2dd6bfca674a
+        .quad   0x0a07e7b1e1834030
+        .quad   0x69a198e64f1ce716
+
+        // 2^100 * 1 * B
+
+        .quad   0x7afcd613efa9d697
+        .quad   0x0cc45aa41c067959
+        .quad   0xa56fe104c1fada96
+        .quad   0x3a73b70472e40365
+        .quad   0x7b26e56b9e2d4734
+        .quad   0xc4c7132b81c61675
+        .quad   0xef5c9525ec9cde7f
+        .quad   0x39c80b16e71743ad
+        .quad   0x0f196e0d1b826c68
+        .quad   0xf71ff0e24960e3db
+        .quad   0x6113167023b7436c
+        .quad   0x0cf0ea5877da7282
+
+        // 2^100 * 2 * B
+
+        .quad   0x196c80a4ddd4ccbd
+        .quad   0x22e6f55d95f2dd9d
+        .quad   0xc75e33c740d6c71b
+        .quad   0x7bb51279cb3c042f
+        .quad   0xe332ced43ba6945a
+        .quad   0xde0b1361e881c05d
+        .quad   0x1ad40f095e67ed3b
+        .quad   0x5da8acdab8c63d5d
+        .quad   0xc4b6664a3a70159f
+        .quad   0x76194f0f0a904e14
+        .quad   0xa5614c39a4096c13
+        .quad   0x6cd0ff50979feced
+
+        // 2^100 * 3 * B
+
+        .quad   0xc0e067e78f4428ac
+        .quad   0x14835ab0a61135e3
+        .quad   0xf21d14f338062935
+        .quad   0x6390a4c8df04849c
+        .quad   0x7fecfabdb04ba18e
+        .quad   0xd0fc7bfc3bddbcf7
+        .quad   0xa41d486e057a131c
+        .quad   0x641a4391f2223a61
+        .quad   0xc5c6b95aa606a8db
+        .quad   0x914b7f9eb06825f1
+        .quad   0x2a731f6b44fc9eff
+        .quad   0x30ddf38562705cfc
+
+        // 2^100 * 4 * B
+
+        .quad   0x4e3dcbdad1bff7f9
+        .quad   0xc9118e8220645717
+        .quad   0xbacccebc0f189d56
+        .quad   0x1b4822e9d4467668
+        .quad   0x33bef2bd68bcd52c
+        .quad   0xc649dbb069482ef2
+        .quad   0xb5b6ee0c41cb1aee
+        .quad   0x5c294d270212a7e5
+        .quad   0xab360a7f25563781
+        .quad   0x2512228a480f7958
+        .quad   0xc75d05276114b4e3
+        .quad   0x222d9625d976fe2a
+
+        // 2^100 * 5 * B
+
+        .quad   0x1c717f85b372ace1
+        .quad   0x81930e694638bf18
+        .quad   0x239cad056bc08b58
+        .quad   0x0b34271c87f8fff4
+        .quad   0x0f94be7e0a344f85
+        .quad   0xeb2faa8c87f22c38
+        .quad   0x9ce1e75e4ee16f0f
+        .quad   0x43e64e5418a08dea
+        .quad   0x8155e2521a35ce63
+        .quad   0xbe100d4df912028e
+        .quad   0xbff80bf8a57ddcec
+        .quad   0x57342dc96d6bc6e4
+
+        // 2^100 * 6 * B
+
+        .quad   0xefeef065c8ce5998
+        .quad   0xbf029510b5cbeaa2
+        .quad   0x8c64a10620b7c458
+        .quad   0x35134fb231c24855
+        .quad   0xf3c3bcb71e707bf6
+        .quad   0x351d9b8c7291a762
+        .quad   0x00502e6edad69a33
+        .quad   0x522f521f1ec8807f
+        .quad   0x272c1f46f9a3902b
+        .quad   0xc91ba3b799657bcc
+        .quad   0xae614b304f8a1c0e
+        .quad   0x7afcaad70b99017b
+
+        // 2^100 * 7 * B
+
+        .quad   0xc25ded54a4b8be41
+        .quad   0x902d13e11bb0e2dd
+        .quad   0x41f43233cde82ab2
+        .quad   0x1085faa5c3aae7cb
+        .quad   0xa88141ecef842b6b
+        .quad   0x55e7b14797abe6c5
+        .quad   0x8c748f9703784ffe
+        .quad   0x5b50a1f7afcd00b7
+        .quad   0x9b840f66f1361315
+        .quad   0x18462242701003e9
+        .quad   0x65ed45fae4a25080
+        .quad   0x0a2862393fda7320
+
+        // 2^100 * 8 * B
+
+        .quad   0x46ab13c8347cbc9d
+        .quad   0x3849e8d499c12383
+        .quad   0x4cea314087d64ac9
+        .quad   0x1f354134b1a29ee7
+        .quad   0x960e737b6ecb9d17
+        .quad   0xfaf24948d67ceae1
+        .quad   0x37e7a9b4d55e1b89
+        .quad   0x5cb7173cb46c59eb
+        .quad   0x4a89e68b82b7abf0
+        .quad   0xf41cd9279ba6b7b9
+        .quad   0x16e6c210e18d876f
+        .quad   0x7cacdb0f7f1b09c6
+
+        // 2^104 * 1 * B
+
+        .quad   0x9062b2e0d91a78bc
+        .quad   0x47c9889cc8509667
+        .quad   0x9df54a66405070b8
+        .quad   0x7369e6a92493a1bf
+        .quad   0xe1014434dcc5caed
+        .quad   0x47ed5d963c84fb33
+        .quad   0x70019576ed86a0e7
+        .quad   0x25b2697bd267f9e4
+        .quad   0x9d673ffb13986864
+        .quad   0x3ca5fbd9415dc7b8
+        .quad   0xe04ecc3bdf273b5e
+        .quad   0x1420683db54e4cd2
+
+        // 2^104 * 2 * B
+
+        .quad   0xb478bd1e249dd197
+        .quad   0x620c35005e58c102
+        .quad   0xfb02d32fccbaac5c
+        .quad   0x60b63bebf508a72d
+        .quad   0x34eebb6fc1cc5ad0
+        .quad   0x6a1b0ce99646ac8b
+        .quad   0xd3b0da49a66bde53
+        .quad   0x31e83b4161d081c1
+        .quad   0x97e8c7129e062b4f
+        .quad   0x49e48f4f29320ad8
+        .quad   0x5bece14b6f18683f
+        .quad   0x55cf1eb62d550317
+
+        // 2^104 * 3 * B
+
+        .quad   0x5879101065c23d58
+        .quad   0x8b9d086d5094819c
+        .quad   0xe2402fa912c55fa7
+        .quad   0x669a6564570891d4
+        .quad   0x3076b5e37df58c52
+        .quad   0xd73ab9dde799cc36
+        .quad   0xbd831ce34913ee20
+        .quad   0x1a56fbaa62ba0133
+        .quad   0x943e6b505c9dc9ec
+        .quad   0x302557bba77c371a
+        .quad   0x9873ae5641347651
+        .quad   0x13c4836799c58a5c
+
+        // 2^104 * 4 * B
+
+        .quad   0x423a5d465ab3e1b9
+        .quad   0xfc13c187c7f13f61
+        .quad   0x19f83664ecb5b9b6
+        .quad   0x66f80c93a637b607
+        .quad   0xc4dcfb6a5d8bd080
+        .quad   0xdeebc4ec571a4842
+        .quad   0xd4b2e883b8e55365
+        .quad   0x50bdc87dc8e5b827
+        .quad   0x606d37836edfe111
+        .quad   0x32353e15f011abd9
+        .quad   0x64b03ac325b73b96
+        .quad   0x1dd56444725fd5ae
+
+        // 2^104 * 5 * B
+
+        .quad   0x8fa47ff83362127d
+        .quad   0xbc9f6ac471cd7c15
+        .quad   0x6e71454349220c8b
+        .quad   0x0e645912219f732e
+        .quad   0xc297e60008bac89a
+        .quad   0x7d4cea11eae1c3e0
+        .quad   0xf3e38be19fe7977c
+        .quad   0x3a3a450f63a305cd
+        .quad   0x078f2f31d8394627
+        .quad   0x389d3183de94a510
+        .quad   0xd1e36c6d17996f80
+        .quad   0x318c8d9393a9a87b
+
+        // 2^104 * 6 * B
+
+        .quad   0xf2745d032afffe19
+        .quad   0x0c9f3c497f24db66
+        .quad   0xbc98d3e3ba8598ef
+        .quad   0x224c7c679a1d5314
+        .quad   0x5d669e29ab1dd398
+        .quad   0xfc921658342d9e3b
+        .quad   0x55851dfdf35973cd
+        .quad   0x509a41c325950af6
+        .quad   0xbdc06edca6f925e9
+        .quad   0x793ef3f4641b1f33
+        .quad   0x82ec12809d833e89
+        .quad   0x05bff02328a11389
+
+        // 2^104 * 7 * B
+
+        .quad   0x3632137023cae00b
+        .quad   0x544acf0ad1accf59
+        .quad   0x96741049d21a1c88
+        .quad   0x780b8cc3fa2a44a7
+        .quad   0x6881a0dd0dc512e4
+        .quad   0x4fe70dc844a5fafe
+        .quad   0x1f748e6b8f4a5240
+        .quad   0x576277cdee01a3ea
+        .quad   0x1ef38abc234f305f
+        .quad   0x9a577fbd1405de08
+        .quad   0x5e82a51434e62a0d
+        .quad   0x5ff418726271b7a1
+
+        // 2^104 * 8 * B
+
+        .quad   0x398e080c1789db9d
+        .quad   0xa7602025f3e778f5
+        .quad   0xfa98894c06bd035d
+        .quad   0x106a03dc25a966be
+        .quad   0xe5db47e813b69540
+        .quad   0xf35d2a3b432610e1
+        .quad   0xac1f26e938781276
+        .quad   0x29d4db8ca0a0cb69
+        .quad   0xd9ad0aaf333353d0
+        .quad   0x38669da5acd309e5
+        .quad   0x3c57658ac888f7f0
+        .quad   0x4ab38a51052cbefa
+
+        // 2^108 * 1 * B
+
+        .quad   0xdfdacbee4324c0e9
+        .quad   0x054442883f955bb7
+        .quad   0xdef7aaa8ea31609f
+        .quad   0x68aee70642287cff
+        .quad   0xf68fe2e8809de054
+        .quad   0xe3bc096a9c82bad1
+        .quad   0x076353d40aadbf45
+        .quad   0x7b9b1fb5dea1959e
+        .quad   0xf01cc8f17471cc0c
+        .quad   0x95242e37579082bb
+        .quad   0x27776093d3e46b5f
+        .quad   0x2d13d55a28bd85fb
+
+        // 2^108 * 2 * B
+
+        .quad   0xfac5d2065b35b8da
+        .quad   0xa8da8a9a85624bb7
+        .quad   0xccd2ca913d21cd0f
+        .quad   0x6b8341ee8bf90d58
+        .quad   0xbf019cce7aee7a52
+        .quad   0xa8ded2b6e454ead3
+        .quad   0x3c619f0b87a8bb19
+        .quad   0x3619b5d7560916d8
+        .quad   0x3579f26b0282c4b2
+        .quad   0x64d592f24fafefae
+        .quad   0xb7cded7b28c8c7c0
+        .quad   0x6a927b6b7173a8d7
+
+        // 2^108 * 3 * B
+
+        .quad   0x1f6db24f986e4656
+        .quad   0x1021c02ed1e9105b
+        .quad   0xf8ff3fff2cc0a375
+        .quad   0x1d2a6bf8c6c82592
+        .quad   0x8d7040863ece88eb
+        .quad   0xf0e307a980eec08c
+        .quad   0xac2250610d788fda
+        .quad   0x056d92a43a0d478d
+        .quad   0x1b05a196fc3da5a1
+        .quad   0x77d7a8c243b59ed0
+        .quad   0x06da3d6297d17918
+        .quad   0x66fbb494f12353f7
+
+        // 2^108 * 4 * B
+
+        .quad   0x751a50b9d85c0fb8
+        .quad   0xd1afdc258bcf097b
+        .quad   0x2f16a6a38309a969
+        .quad   0x14ddff9ee5b00659
+        .quad   0xd6d70996f12309d6
+        .quad   0xdbfb2385e9c3d539
+        .quad   0x46d602b0f7552411
+        .quad   0x270a0b0557843e0c
+        .quad   0x61ff0640a7862bcc
+        .quad   0x81cac09a5f11abfe
+        .quad   0x9047830455d12abb
+        .quad   0x19a4bde1945ae873
+
+        // 2^108 * 5 * B
+
+        .quad   0x9b9f26f520a6200a
+        .quad   0x64804443cf13eaf8
+        .quad   0x8a63673f8631edd3
+        .quad   0x72bbbce11ed39dc1
+        .quad   0x40c709dec076c49f
+        .quad   0x657bfaf27f3e53f6
+        .quad   0x40662331eca042c4
+        .quad   0x14b375487eb4df04
+        .quad   0xae853c94ab66dc47
+        .quad   0xeb62343edf762d6e
+        .quad   0xf08e0e186fb2f7d1
+        .quad   0x4f0b1c02700ab37a
+
+        // 2^108 * 6 * B
+
+        .quad   0xe1706787d81951fa
+        .quad   0xa10a2c8eb290c77b
+        .quad   0xe7382fa03ed66773
+        .quad   0x0a4d84710bcc4b54
+        .quad   0x79fd21ccc1b2e23f
+        .quad   0x4ae7c281453df52a
+        .quad   0xc8172ec9d151486b
+        .quad   0x68abe9443e0a7534
+        .quad   0xda12c6c407831dcb
+        .quad   0x0da230d74d5c510d
+        .quad   0x4ab1531e6bd404e1
+        .quad   0x4106b166bcf440ef
+
+        // 2^108 * 7 * B
+
+        .quad   0x02e57a421cd23668
+        .quad   0x4ad9fb5d0eaef6fd
+        .quad   0x954e6727b1244480
+        .quad   0x7f792f9d2699f331
+        .quad   0xa485ccd539e4ecf2
+        .quad   0x5aa3f3ad0555bab5
+        .quad   0x145e3439937df82d
+        .quad   0x1238b51e1214283f
+        .quad   0x0b886b925fd4d924
+        .quad   0x60906f7a3626a80d
+        .quad   0xecd367b4b98abd12
+        .quad   0x2876beb1def344cf
+
+        // 2^108 * 8 * B
+
+        .quad   0xdc84e93563144691
+        .quad   0x632fe8a0d61f23f4
+        .quad   0x4caa800612a9a8d5
+        .quad   0x48f9dbfa0e9918d3
+        .quad   0xd594b3333a8a85f8
+        .quad   0x4ea37689e78d7d58
+        .quad   0x73bf9f455e8e351f
+        .quad   0x5507d7d2bc41ebb4
+        .quad   0x1ceb2903299572fc
+        .quad   0x7c8ccaa29502d0ee
+        .quad   0x91bfa43411cce67b
+        .quad   0x5784481964a831e7
+
+        // 2^112 * 1 * B
+
+        .quad   0xda7c2b256768d593
+        .quad   0x98c1c0574422ca13
+        .quad   0xf1a80bd5ca0ace1d
+        .quad   0x29cdd1adc088a690
+        .quad   0xd6cfd1ef5fddc09c
+        .quad   0xe82b3efdf7575dce
+        .quad   0x25d56b5d201634c2
+        .quad   0x3041c6bb04ed2b9b
+        .quad   0x0ff2f2f9d956e148
+        .quad   0xade797759f356b2e
+        .quad   0x1a4698bb5f6c025c
+        .quad   0x104bbd6814049a7b
+
+        // 2^112 * 2 * B
+
+        .quad   0x51f0fd3168f1ed67
+        .quad   0x2c811dcdd86f3bc2
+        .quad   0x44dc5c4304d2f2de
+        .quad   0x5be8cc57092a7149
+        .quad   0xa95d9a5fd67ff163
+        .quad   0xe92be69d4cc75681
+        .quad   0xb7f8024cde20f257
+        .quad   0x204f2a20fb072df5
+        .quad   0xc8143b3d30ebb079
+        .quad   0x7589155abd652e30
+        .quad   0x653c3c318f6d5c31
+        .quad   0x2570fb17c279161f
+
+        // 2^112 * 3 * B
+
+        .quad   0x3efa367f2cb61575
+        .quad   0xf5f96f761cd6026c
+        .quad   0xe8c7142a65b52562
+        .quad   0x3dcb65ea53030acd
+        .quad   0x192ea9550bb8245a
+        .quad   0xc8e6fba88f9050d1
+        .quad   0x7986ea2d88a4c935
+        .quad   0x241c5f91de018668
+        .quad   0x28d8172940de6caa
+        .quad   0x8fbf2cf022d9733a
+        .quad   0x16d7fcdd235b01d1
+        .quad   0x08420edd5fcdf0e5
+
+        // 2^112 * 4 * B
+
+        .quad   0xcdff20ab8362fa4a
+        .quad   0x57e118d4e21a3e6e
+        .quad   0xe3179617fc39e62b
+        .quad   0x0d9a53efbc1769fd
+        .quad   0x0358c34e04f410ce
+        .quad   0xb6135b5a276e0685
+        .quad   0x5d9670c7ebb91521
+        .quad   0x04d654f321db889c
+        .quad   0x5e7dc116ddbdb5d5
+        .quad   0x2954deb68da5dd2d
+        .quad   0x1cb608173334a292
+        .quad   0x4a7a4f2618991ad7
+
+        // 2^112 * 5 * B
+
+        .quad   0xf4a718025fb15f95
+        .quad   0x3df65f346b5c1b8f
+        .quad   0xcdfcf08500e01112
+        .quad   0x11b50c4cddd31848
+        .quad   0x24c3b291af372a4b
+        .quad   0x93da8270718147f2
+        .quad   0xdd84856486899ef2
+        .quad   0x4a96314223e0ee33
+        .quad   0xa6e8274408a4ffd6
+        .quad   0x738e177e9c1576d9
+        .quad   0x773348b63d02b3f2
+        .quad   0x4f4bce4dce6bcc51
+
+        // 2^112 * 6 * B
+
+        .quad   0xa71fce5ae2242584
+        .quad   0x26ea725692f58a9e
+        .quad   0xd21a09d71cea3cf4
+        .quad   0x73fcdd14b71c01e6
+        .quad   0x30e2616ec49d0b6f
+        .quad   0xe456718fcaec2317
+        .quad   0x48eb409bf26b4fa6
+        .quad   0x3042cee561595f37
+        .quad   0x427e7079449bac41
+        .quad   0x855ae36dbce2310a
+        .quad   0x4cae76215f841a7c
+        .quad   0x389e740c9a9ce1d6
+
+        // 2^112 * 7 * B
+
+        .quad   0x64fcb3ae34dcb9ce
+        .quad   0x97500323e348d0ad
+        .quad   0x45b3f07d62c6381b
+        .quad   0x61545379465a6788
+        .quad   0xc9bd78f6570eac28
+        .quad   0xe55b0b3227919ce1
+        .quad   0x65fc3eaba19b91ed
+        .quad   0x25c425e5d6263690
+        .quad   0x3f3e06a6f1d7de6e
+        .quad   0x3ef976278e062308
+        .quad   0x8c14f6264e8a6c77
+        .quad   0x6539a08915484759
+
+        // 2^112 * 8 * B
+
+        .quad   0xe9d21f74c3d2f773
+        .quad   0xc150544125c46845
+        .quad   0x624e5ce8f9b99e33
+        .quad   0x11c5e4aac5cd186c
+        .quad   0xddc4dbd414bb4a19
+        .quad   0x19b2bc3c98424f8e
+        .quad   0x48a89fd736ca7169
+        .quad   0x0f65320ef019bd90
+        .quad   0xd486d1b1cafde0c6
+        .quad   0x4f3fe6e3163b5181
+        .quad   0x59a8af0dfaf2939a
+        .quad   0x4cabc7bdec33072a
+
+        // 2^116 * 1 * B
+
+        .quad   0x16faa8fb532f7428
+        .quad   0xdbd42ea046a4e272
+        .quad   0x5337653b8b9ea480
+        .quad   0x4065947223973f03
+        .quad   0xf7c0a19c1a54a044
+        .quad   0x4a1c5e2477bd9fbb
+        .quad   0xa6e3ca115af22972
+        .quad   0x1819bb953f2e9e0d
+        .quad   0x498fbb795e042e84
+        .quad   0x7d0dd89a7698b714
+        .quad   0x8bfb0ba427fe6295
+        .quad   0x36ba82e721200524
+
+        // 2^116 * 2 * B
+
+        .quad   0xd60ecbb74245ec41
+        .quad   0xfd9be89e34348716
+        .quad   0xc9240afee42284de
+        .quad   0x4472f648d0531db4
+        .quad   0xc8d69d0a57274ed5
+        .quad   0x45ba803260804b17
+        .quad   0xdf3cda102255dfac
+        .quad   0x77d221232709b339
+        .quad   0x498a6d7064ad94d8
+        .quad   0xa5b5c8fd9af62263
+        .quad   0x8ca8ed0545c141f4
+        .quad   0x2c63bec3662d358c
+
+        // 2^116 * 3 * B
+
+        .quad   0x7fe60d8bea787955
+        .quad   0xb9dc117eb5f401b7
+        .quad   0x91c7c09a19355cce
+        .quad   0x22692ef59442bedf
+        .quad   0x9a518b3a8586f8bf
+        .quad   0x9ee71af6cbb196f0
+        .quad   0xaa0625e6a2385cf2
+        .quad   0x1deb2176ddd7c8d1
+        .quad   0x8563d19a2066cf6c
+        .quad   0x401bfd8c4dcc7cd7
+        .quad   0xd976a6becd0d8f62
+        .quad   0x67cfd773a278b05e
+
+        // 2^116 * 4 * B
+
+        .quad   0x8dec31faef3ee475
+        .quad   0x99dbff8a9e22fd92
+        .quad   0x512d11594e26cab1
+        .quad   0x0cde561eec4310b9
+        .quad   0x2d5fa9855a4e586a
+        .quad   0x65f8f7a449beab7e
+        .quad   0xaa074dddf21d33d3
+        .quad   0x185cba721bcb9dee
+        .quad   0x93869da3f4e3cb41
+        .quad   0xbf0392f540f7977e
+        .quad   0x026204fcd0463b83
+        .quad   0x3ec91a769eec6eed
+
+        // 2^116 * 5 * B
+
+        .quad   0x1e9df75bf78166ad
+        .quad   0x4dfda838eb0cd7af
+        .quad   0xba002ed8c1eaf988
+        .quad   0x13fedb3e11f33cfc
+        .quad   0x0fad2fb7b0a3402f
+        .quad   0x46615ecbfb69f4a8
+        .quad   0xf745bcc8c5f8eaa6
+        .quad   0x7a5fa8794a94e896
+        .quad   0x52958faa13cd67a1
+        .quad   0x965ee0818bdbb517
+        .quad   0x16e58daa2e8845b3
+        .quad   0x357d397d5499da8f
+
+        // 2^116 * 6 * B
+
+        .quad   0x1ebfa05fb0bace6c
+        .quad   0xc934620c1caf9a1e
+        .quad   0xcc771cc41d82b61a
+        .quad   0x2d94a16aa5f74fec
+        .quad   0x481dacb4194bfbf8
+        .quad   0x4d77e3f1bae58299
+        .quad   0x1ef4612e7d1372a0
+        .quad   0x3a8d867e70ff69e1
+        .quad   0x6f58cd5d55aff958
+        .quad   0xba3eaa5c75567721
+        .quad   0x75c123999165227d
+        .quad   0x69be1343c2f2b35e
+
+        // 2^116 * 7 * B
+
+        .quad   0x0e091d5ee197c92a
+        .quad   0x4f51019f2945119f
+        .quad   0x143679b9f034e99c
+        .quad   0x7d88112e4d24c696
+        .quad   0x82bbbdac684b8de3
+        .quad   0xa2f4c7d03fca0718
+        .quad   0x337f92fbe096aaa8
+        .quad   0x200d4d8c63587376
+        .quad   0x208aed4b4893b32b
+        .quad   0x3efbf23ebe59b964
+        .quad   0xd762deb0dba5e507
+        .quad   0x69607bd681bd9d94
+
+        // 2^116 * 8 * B
+
+        .quad   0xf6be021068de1ce1
+        .quad   0xe8d518e70edcbc1f
+        .quad   0xe3effdd01b5505a5
+        .quad   0x35f63353d3ec3fd0
+        .quad   0x3b7f3bd49323a902
+        .quad   0x7c21b5566b2c6e53
+        .quad   0xe5ba8ff53a7852a7
+        .quad   0x28bc77a5838ece00
+        .quad   0x63ba78a8e25d8036
+        .quad   0x63651e0094333490
+        .quad   0x48d82f20288ce532
+        .quad   0x3a31abfa36b57524
+
+        // 2^120 * 1 * B
+
+        .quad   0x239e9624089c0a2e
+        .quad   0xc748c4c03afe4738
+        .quad   0x17dbed2a764fa12a
+        .quad   0x639b93f0321c8582
+        .quad   0xc08f788f3f78d289
+        .quad   0xfe30a72ca1404d9f
+        .quad   0xf2778bfccf65cc9d
+        .quad   0x7ee498165acb2021
+        .quad   0x7bd508e39111a1c3
+        .quad   0x2b2b90d480907489
+        .quad   0xe7d2aec2ae72fd19
+        .quad   0x0edf493c85b602a6
+
+        // 2^120 * 2 * B
+
+        .quad   0xaecc8158599b5a68
+        .quad   0xea574f0febade20e
+        .quad   0x4fe41d7422b67f07
+        .quad   0x403b92e3019d4fb4
+        .quad   0x6767c4d284764113
+        .quad   0xa090403ff7f5f835
+        .quad   0x1c8fcffacae6bede
+        .quad   0x04c00c54d1dfa369
+        .quad   0x4dc22f818b465cf8
+        .quad   0x71a0f35a1480eff8
+        .quad   0xaee8bfad04c7d657
+        .quad   0x355bb12ab26176f4
+
+        // 2^120 * 3 * B
+
+        .quad   0xa71e64cc7493bbf4
+        .quad   0xe5bd84d9eca3b0c3
+        .quad   0x0a6bc50cfa05e785
+        .quad   0x0f9b8132182ec312
+        .quad   0xa301dac75a8c7318
+        .quad   0xed90039db3ceaa11
+        .quad   0x6f077cbf3bae3f2d
+        .quad   0x7518eaf8e052ad8e
+        .quad   0xa48859c41b7f6c32
+        .quad   0x0f2d60bcf4383298
+        .quad   0x1815a929c9b1d1d9
+        .quad   0x47c3871bbb1755c4
+
+        // 2^120 * 4 * B
+
+        .quad   0x5144539771ec4f48
+        .quad   0xf805b17dc98c5d6e
+        .quad   0xf762c11a47c3c66b
+        .quad   0x00b89b85764699dc
+        .quad   0xfbe65d50c85066b0
+        .quad   0x62ecc4b0b3a299b0
+        .quad   0xe53754ea441ae8e0
+        .quad   0x08fea02ce8d48d5f
+        .quad   0x824ddd7668deead0
+        .quad   0xc86445204b685d23
+        .quad   0xb514cfcd5d89d665
+        .quad   0x473829a74f75d537
+
+        // 2^120 * 5 * B
+
+        .quad   0x82d2da754679c418
+        .quad   0xe63bd7d8b2618df0
+        .quad   0x355eef24ac47eb0a
+        .quad   0x2078684c4833c6b4
+        .quad   0x23d9533aad3902c9
+        .quad   0x64c2ddceef03588f
+        .quad   0x15257390cfe12fb4
+        .quad   0x6c668b4d44e4d390
+        .quad   0x3b48cf217a78820c
+        .quad   0xf76a0ab281273e97
+        .quad   0xa96c65a78c8eed7b
+        .quad   0x7411a6054f8a433f
+
+        // 2^120 * 6 * B
+
+        .quad   0x4d659d32b99dc86d
+        .quad   0x044cdc75603af115
+        .quad   0xb34c712cdcc2e488
+        .quad   0x7c136574fb8134ff
+        .quad   0x579ae53d18b175b4
+        .quad   0x68713159f392a102
+        .quad   0x8455ecba1eef35f5
+        .quad   0x1ec9a872458c398f
+        .quad   0xb8e6a4d400a2509b
+        .quad   0x9b81d7020bc882b4
+        .quad   0x57e7cc9bf1957561
+        .quad   0x3add88a5c7cd6460
+
+        // 2^120 * 7 * B
+
+        .quad   0xab895770b635dcf2
+        .quad   0x02dfef6cf66c1fbc
+        .quad   0x85530268beb6d187
+        .quad   0x249929fccc879e74
+        .quad   0x85c298d459393046
+        .quad   0x8f7e35985ff659ec
+        .quad   0x1d2ca22af2f66e3a
+        .quad   0x61ba1131a406a720
+        .quad   0xa3d0a0f116959029
+        .quad   0x023b6b6cba7ebd89
+        .quad   0x7bf15a3e26783307
+        .quad   0x5620310cbbd8ece7
+
+        // 2^120 * 8 * B
+
+        .quad   0x528993434934d643
+        .quad   0xb9dbf806a51222f5
+        .quad   0x8f6d878fc3f41c22
+        .quad   0x37676a2a4d9d9730
+        .quad   0x6646b5f477e285d6
+        .quad   0x40e8ff676c8f6193
+        .quad   0xa6ec7311abb594dd
+        .quad   0x7ec846f3658cec4d
+        .quad   0x9b5e8f3f1da22ec7
+        .quad   0x130f1d776c01cd13
+        .quad   0x214c8fcfa2989fb8
+        .quad   0x6daaf723399b9dd5
+
+        // 2^124 * 1 * B
+
+        .quad   0x591e4a5610628564
+        .quad   0x2a4bb87ca8b4df34
+        .quad   0xde2a2572e7a38e43
+        .quad   0x3cbdabd9fee5046e
+        .quad   0x81aebbdd2cd13070
+        .quad   0x962e4325f85a0e9e
+        .quad   0xde9391aacadffecb
+        .quad   0x53177fda52c230e6
+        .quad   0xa7bc970650b9de79
+        .quad   0x3d12a7fbc301b59b
+        .quad   0x02652e68d36ae38c
+        .quad   0x79d739835a6199dc
+
+        // 2^124 * 2 * B
+
+        .quad   0xd9354df64131c1bd
+        .quad   0x758094a186ec5822
+        .quad   0x4464ee12e459f3c2
+        .quad   0x6c11fce4cb133282
+        .quad   0x21c9d9920d591737
+        .quad   0x9bea41d2e9b46cd6
+        .quad   0xe20e84200d89bfca
+        .quad   0x79d99f946eae5ff8
+        .quad   0xf17b483568673205
+        .quad   0x387deae83caad96c
+        .quad   0x61b471fd56ffe386
+        .quad   0x31741195b745a599
+
+        // 2^124 * 3 * B
+
+        .quad   0xe8d10190b77a360b
+        .quad   0x99b983209995e702
+        .quad   0xbd4fdff8fa0247aa
+        .quad   0x2772e344e0d36a87
+        .quad   0x17f8ba683b02a047
+        .quad   0x50212096feefb6c8
+        .quad   0x70139be21556cbe2
+        .quad   0x203e44a11d98915b
+        .quad   0xd6863eba37b9e39f
+        .quad   0x105bc169723b5a23
+        .quad   0x104f6459a65c0762
+        .quad   0x567951295b4d38d4
+
+        // 2^124 * 4 * B
+
+        .quad   0x535fd60613037524
+        .quad   0xe210adf6b0fbc26a
+        .quad   0xac8d0a9b23e990ae
+        .quad   0x47204d08d72fdbf9
+        .quad   0x07242eb30d4b497f
+        .quad   0x1ef96306b9bccc87
+        .quad   0x37950934d8116f45
+        .quad   0x05468d6201405b04
+        .quad   0x00f565a9f93267de
+        .quad   0xcecfd78dc0d58e8a
+        .quad   0xa215e2dcf318e28e
+        .quad   0x4599ee919b633352
+
+        // 2^124 * 5 * B
+
+        .quad   0xd3c220ca70e0e76b
+        .quad   0xb12bea58ea9f3094
+        .quad   0x294ddec8c3271282
+        .quad   0x0c3539e1a1d1d028
+        .quad   0xac746d6b861ae579
+        .quad   0x31ab0650f6aea9dc
+        .quad   0x241d661140256d4c
+        .quad   0x2f485e853d21a5de
+        .quad   0x329744839c0833f3
+        .quad   0x6fe6257fd2abc484
+        .quad   0x5327d1814b358817
+        .quad   0x65712585893fe9bc
+
+        // 2^124 * 6 * B
+
+        .quad   0x9c102fb732a61161
+        .quad   0xe48e10dd34d520a8
+        .quad   0x365c63546f9a9176
+        .quad   0x32f6fe4c046f6006
+        .quad   0x81c29f1bd708ee3f
+        .quad   0xddcb5a05ae6407d0
+        .quad   0x97aec1d7d2a3eba7
+        .quad   0x1590521a91d50831
+        .quad   0x40a3a11ec7910acc
+        .quad   0x9013dff8f16d27ae
+        .quad   0x1a9720d8abb195d4
+        .quad   0x1bb9fe452ea98463
+
+        // 2^124 * 7 * B
+
+        .quad   0xe9d1d950b3d54f9e
+        .quad   0x2d5f9cbee00d33c1
+        .quad   0x51c2c656a04fc6ac
+        .quad   0x65c091ee3c1cbcc9
+        .quad   0xcf5e6c95cc36747c
+        .quad   0x294201536b0bc30d
+        .quad   0x453ac67cee797af0
+        .quad   0x5eae6ab32a8bb3c9
+        .quad   0x7083661114f118ea
+        .quad   0x2b37b87b94349cad
+        .quad   0x7273f51cb4e99f40
+        .quad   0x78a2a95823d75698
+
+        // 2^124 * 8 * B
+
+        .quad   0xa2b072e95c8c2ace
+        .quad   0x69cffc96651e9c4b
+        .quad   0x44328ef842e7b42b
+        .quad   0x5dd996c122aadeb3
+        .quad   0xb4f23c425ef83207
+        .quad   0xabf894d3c9a934b5
+        .quad   0xd0708c1339fd87f7
+        .quad   0x1876789117166130
+        .quad   0x925b5ef0670c507c
+        .quad   0x819bc842b93c33bf
+        .quad   0x10792e9a70dd003f
+        .quad   0x59ad4b7a6e28dc74
+
+        // 2^128 * 1 * B
+
+        .quad   0x5f3a7562eb3dbe47
+        .quad   0xf7ea38548ebda0b8
+        .quad   0x00c3e53145747299
+        .quad   0x1304e9e71627d551
+        .quad   0x583b04bfacad8ea2
+        .quad   0x29b743e8148be884
+        .quad   0x2b1e583b0810c5db
+        .quad   0x2b5449e58eb3bbaa
+        .quad   0x789814d26adc9cfe
+        .quad   0x3c1bab3f8b48dd0b
+        .quad   0xda0fe1fff979c60a
+        .quad   0x4468de2d7c2dd693
+
+        // 2^128 * 2 * B
+
+        .quad   0x51bb355e9419469e
+        .quad   0x33e6dc4c23ddc754
+        .quad   0x93a5b6d6447f9962
+        .quad   0x6cce7c6ffb44bd63
+        .quad   0x4b9ad8c6f86307ce
+        .quad   0x21113531435d0c28
+        .quad   0xd4a866c5657a772c
+        .quad   0x5da6427e63247352
+        .quad   0x1a94c688deac22ca
+        .quad   0xb9066ef7bbae1ff8
+        .quad   0x88ad8c388d59580f
+        .quad   0x58f29abfe79f2ca8
+
+        // 2^128 * 3 * B
+
+        .quad   0xe90ecfab8de73e68
+        .quad   0x54036f9f377e76a5
+        .quad   0xf0495b0bbe015982
+        .quad   0x577629c4a7f41e36
+        .quad   0x4b5a64bf710ecdf6
+        .quad   0xb14ce538462c293c
+        .quad   0x3643d056d50b3ab9
+        .quad   0x6af93724185b4870
+        .quad   0x3220024509c6a888
+        .quad   0xd2e036134b558973
+        .quad   0x83e236233c33289f
+        .quad   0x701f25bb0caec18f
+
+        // 2^128 * 4 * B
+
+        .quad   0xc3a8b0f8e4616ced
+        .quad   0xf700660e9e25a87d
+        .quad   0x61e3061ff4bca59c
+        .quad   0x2e0c92bfbdc40be9
+        .quad   0x9d18f6d97cbec113
+        .quad   0x844a06e674bfdbe4
+        .quad   0x20f5b522ac4e60d6
+        .quad   0x720a5bc050955e51
+        .quad   0x0c3f09439b805a35
+        .quad   0xe84e8b376242abfc
+        .quad   0x691417f35c229346
+        .quad   0x0e9b9cbb144ef0ec
+
+        // 2^128 * 5 * B
+
+        .quad   0xfbbad48ffb5720ad
+        .quad   0xee81916bdbf90d0e
+        .quad   0xd4813152635543bf
+        .quad   0x221104eb3f337bd8
+        .quad   0x8dee9bd55db1beee
+        .quad   0xc9c3ab370a723fb9
+        .quad   0x44a8f1bf1c68d791
+        .quad   0x366d44191cfd3cde
+        .quad   0x9e3c1743f2bc8c14
+        .quad   0x2eda26fcb5856c3b
+        .quad   0xccb82f0e68a7fb97
+        .quad   0x4167a4e6bc593244
+
+        // 2^128 * 6 * B
+
+        .quad   0x643b9d2876f62700
+        .quad   0x5d1d9d400e7668eb
+        .quad   0x1b4b430321fc0684
+        .quad   0x7938bb7e2255246a
+        .quad   0xc2be2665f8ce8fee
+        .quad   0xe967ff14e880d62c
+        .quad   0xf12e6e7e2f364eee
+        .quad   0x34b33370cb7ed2f6
+        .quad   0xcdc591ee8681d6cc
+        .quad   0xce02109ced85a753
+        .quad   0xed7485c158808883
+        .quad   0x1176fc6e2dfe65e4
+
+        // 2^128 * 7 * B
+
+        .quad   0xb4af6cd05b9c619b
+        .quad   0x2ddfc9f4b2a58480
+        .quad   0x3d4fa502ebe94dc4
+        .quad   0x08fc3a4c677d5f34
+        .quad   0xdb90e28949770eb8
+        .quad   0x98fbcc2aacf440a3
+        .quad   0x21354ffeded7879b
+        .quad   0x1f6a3e54f26906b6
+        .quad   0x60a4c199d30734ea
+        .quad   0x40c085b631165cd6
+        .quad   0xe2333e23f7598295
+        .quad   0x4f2fad0116b900d1
+
+        // 2^128 * 8 * B
+
+        .quad   0x44beb24194ae4e54
+        .quad   0x5f541c511857ef6c
+        .quad   0xa61e6b2d368d0498
+        .quad   0x445484a4972ef7ab
+        .quad   0x962cd91db73bb638
+        .quad   0xe60577aafc129c08
+        .quad   0x6f619b39f3b61689
+        .quad   0x3451995f2944ee81
+        .quad   0x9152fcd09fea7d7c
+        .quad   0x4a816c94b0935cf6
+        .quad   0x258e9aaa47285c40
+        .quad   0x10b89ca6042893b7
+
+        // 2^132 * 1 * B
+
+        .quad   0x9b2a426e3b646025
+        .quad   0x32127190385ce4cf
+        .quad   0xa25cffc2dd6dea45
+        .quad   0x06409010bea8de75
+        .quad   0xd67cded679d34aa0
+        .quad   0xcc0b9ec0cc4db39f
+        .quad   0xa535a456e35d190f
+        .quad   0x2e05d9eaf61f6fef
+        .quad   0xc447901ad61beb59
+        .quad   0x661f19bce5dc880a
+        .quad   0x24685482b7ca6827
+        .quad   0x293c778cefe07f26
+
+        // 2^132 * 2 * B
+
+        .quad   0x86809e7007069096
+        .quad   0xaad75b15e4e50189
+        .quad   0x07f35715a21a0147
+        .quad   0x0487f3f112815d5e
+        .quad   0x16c795d6a11ff200
+        .quad   0xcb70d0e2b15815c9
+        .quad   0x89f293209b5395b5
+        .quad   0x50b8c2d031e47b4f
+        .quad   0x48350c08068a4962
+        .quad   0x6ffdd05351092c9a
+        .quad   0x17af4f4aaf6fc8dd
+        .quad   0x4b0553b53cdba58b
+
+        // 2^132 * 3 * B
+
+        .quad   0x9c65fcbe1b32ff79
+        .quad   0xeb75ea9f03b50f9b
+        .quad   0xfced2a6c6c07e606
+        .quad   0x35106cd551717908
+        .quad   0xbf05211b27c152d4
+        .quad   0x5ec26849bd1af639
+        .quad   0x5e0b2caa8e6fab98
+        .quad   0x054c8bdd50bd0840
+        .quad   0x38a0b12f1dcf073d
+        .quad   0x4b60a8a3b7f6a276
+        .quad   0xfed5ac25d3404f9a
+        .quad   0x72e82d5e5505c229
+
+        // 2^132 * 4 * B
+
+        .quad   0x6b0b697ff0d844c8
+        .quad   0xbb12f85cd979cb49
+        .quad   0xd2a541c6c1da0f1f
+        .quad   0x7b7c242958ce7211
+        .quad   0x00d9cdfd69771d02
+        .quad   0x410276cd6cfbf17e
+        .quad   0x4c45306c1cb12ec7
+        .quad   0x2857bf1627500861
+        .quad   0x9f21903f0101689e
+        .quad   0xd779dfd3bf861005
+        .quad   0xa122ee5f3deb0f1b
+        .quad   0x510df84b485a00d4
+
+        // 2^132 * 5 * B
+
+        .quad   0xa54133bb9277a1fa
+        .quad   0x74ec3b6263991237
+        .quad   0x1a3c54dc35d2f15a
+        .quad   0x2d347144e482ba3a
+        .quad   0x24b3c887c70ac15e
+        .quad   0xb0f3a557fb81b732
+        .quad   0x9b2cde2fe578cc1b
+        .quad   0x4cf7ed0703b54f8e
+        .quad   0x6bd47c6598fbee0f
+        .quad   0x9e4733e2ab55be2d
+        .quad   0x1093f624127610c5
+        .quad   0x4e05e26ad0a1eaa4
+
+        // 2^132 * 6 * B
+
+        .quad   0xda9b6b624b531f20
+        .quad   0x429a760e77509abb
+        .quad   0xdbe9f522e823cb80
+        .quad   0x618f1856880c8f82
+        .quad   0x1833c773e18fe6c0
+        .quad   0xe3c4711ad3c87265
+        .quad   0x3bfd3c4f0116b283
+        .quad   0x1955875eb4cd4db8
+        .quad   0x6da6de8f0e399799
+        .quad   0x7ad61aa440fda178
+        .quad   0xb32cd8105e3563dd
+        .quad   0x15f6beae2ae340ae
+
+        // 2^132 * 7 * B
+
+        .quad   0x862bcb0c31ec3a62
+        .quad   0x810e2b451138f3c2
+        .quad   0x788ec4b839dac2a4
+        .quad   0x28f76867ae2a9281
+        .quad   0xba9a0f7b9245e215
+        .quad   0xf368612dd98c0dbb
+        .quad   0x2e84e4cbf220b020
+        .quad   0x6ba92fe962d90eda
+        .quad   0x3e4df9655884e2aa
+        .quad   0xbd62fbdbdbd465a5
+        .quad   0xd7596caa0de9e524
+        .quad   0x6e8042ccb2b1b3d7
+
+        // 2^132 * 8 * B
+
+        .quad   0xf10d3c29ce28ca6e
+        .quad   0xbad34540fcb6093d
+        .quad   0xe7426ed7a2ea2d3f
+        .quad   0x08af9d4e4ff298b9
+        .quad   0x1530653616521f7e
+        .quad   0x660d06b896203dba
+        .quad   0x2d3989bc545f0879
+        .quad   0x4b5303af78ebd7b0
+        .quad   0x72f8a6c3bebcbde8
+        .quad   0x4f0fca4adc3a8e89
+        .quad   0x6fa9d4e8c7bfdf7a
+        .quad   0x0dcf2d679b624eb7
+
+        // 2^136 * 1 * B
+
+        .quad   0x3d5947499718289c
+        .quad   0x12ebf8c524533f26
+        .quad   0x0262bfcb14c3ef15
+        .quad   0x20b878d577b7518e
+        .quad   0x753941be5a45f06e
+        .quad   0xd07caeed6d9c5f65
+        .quad   0x11776b9c72ff51b6
+        .quad   0x17d2d1d9ef0d4da9
+        .quad   0x27f2af18073f3e6a
+        .quad   0xfd3fe519d7521069
+        .quad   0x22e3b72c3ca60022
+        .quad   0x72214f63cc65c6a7
+
+        // 2^136 * 2 * B
+
+        .quad   0xb4e37f405307a693
+        .quad   0xaba714d72f336795
+        .quad   0xd6fbd0a773761099
+        .quad   0x5fdf48c58171cbc9
+        .quad   0x1d9db7b9f43b29c9
+        .quad   0xd605824a4f518f75
+        .quad   0xf2c072bd312f9dc4
+        .quad   0x1f24ac855a1545b0
+        .quad   0x24d608328e9505aa
+        .quad   0x4748c1d10c1420ee
+        .quad   0xc7ffe45c06fb25a2
+        .quad   0x00ba739e2ae395e6
+
+        // 2^136 * 3 * B
+
+        .quad   0x592e98de5c8790d6
+        .quad   0xe5bfb7d345c2a2df
+        .quad   0x115a3b60f9b49922
+        .quad   0x03283a3e67ad78f3
+        .quad   0xae4426f5ea88bb26
+        .quad   0x360679d984973bfb
+        .quad   0x5c9f030c26694e50
+        .quad   0x72297de7d518d226
+        .quad   0x48241dc7be0cb939
+        .quad   0x32f19b4d8b633080
+        .quad   0xd3dfc90d02289308
+        .quad   0x05e1296846271945
+
+        // 2^136 * 4 * B
+
+        .quad   0xba82eeb32d9c495a
+        .quad   0xceefc8fcf12bb97c
+        .quad   0xb02dabae93b5d1e0
+        .quad   0x39c00c9c13698d9b
+        .quad   0xadbfbbc8242c4550
+        .quad   0xbcc80cecd03081d9
+        .quad   0x843566a6f5c8df92
+        .quad   0x78cf25d38258ce4c
+        .quad   0x15ae6b8e31489d68
+        .quad   0xaa851cab9c2bf087
+        .quad   0xc9a75a97f04efa05
+        .quad   0x006b52076b3ff832
+
+        // 2^136 * 5 * B
+
+        .quad   0x29e0cfe19d95781c
+        .quad   0xb681df18966310e2
+        .quad   0x57df39d370516b39
+        .quad   0x4d57e3443bc76122
+        .quad   0xf5cb7e16b9ce082d
+        .quad   0x3407f14c417abc29
+        .quad   0xd4b36bce2bf4a7ab
+        .quad   0x7de2e9561a9f75ce
+        .quad   0xde70d4f4b6a55ecb
+        .quad   0x4801527f5d85db99
+        .quad   0xdbc9c440d3ee9a81
+        .quad   0x6b2a90af1a6029ed
+
+        // 2^136 * 6 * B
+
+        .quad   0x6923f4fc9ae61e97
+        .quad   0x5735281de03f5fd1
+        .quad   0xa764ae43e6edd12d
+        .quad   0x5fd8f4e9d12d3e4a
+        .quad   0x77ebf3245bb2d80a
+        .quad   0xd8301b472fb9079b
+        .quad   0xc647e6f24cee7333
+        .quad   0x465812c8276c2109
+        .quad   0x4d43beb22a1062d9
+        .quad   0x7065fb753831dc16
+        .quad   0x180d4a7bde2968d7
+        .quad   0x05b32c2b1cb16790
+
+        // 2^136 * 7 * B
+
+        .quad   0xc8c05eccd24da8fd
+        .quad   0xa1cf1aac05dfef83
+        .quad   0xdbbeeff27df9cd61
+        .quad   0x3b5556a37b471e99
+        .quad   0xf7fca42c7ad58195
+        .quad   0x3214286e4333f3cc
+        .quad   0xb6c29d0d340b979d
+        .quad   0x31771a48567307e1
+        .quad   0x32b0c524e14dd482
+        .quad   0xedb351541a2ba4b6
+        .quad   0xa3d16048282b5af3
+        .quad   0x4fc079d27a7336eb
+
+        // 2^136 * 8 * B
+
+        .quad   0x51c938b089bf2f7f
+        .quad   0x2497bd6502dfe9a7
+        .quad   0xffffc09c7880e453
+        .quad   0x124567cecaf98e92
+        .quad   0xdc348b440c86c50d
+        .quad   0x1337cbc9cc94e651
+        .quad   0x6422f74d643e3cb9
+        .quad   0x241170c2bae3cd08
+        .quad   0x3ff9ab860ac473b4
+        .quad   0xf0911dee0113e435
+        .quad   0x4ae75060ebc6c4af
+        .quad   0x3f8612966c87000d
+
+        // 2^140 * 1 * B
+
+        .quad   0x0c9c5303f7957be4
+        .quad   0xa3c31a20e085c145
+        .quad   0xb0721d71d0850050
+        .quad   0x0aba390eab0bf2da
+        .quad   0x529fdffe638c7bf3
+        .quad   0xdf2b9e60388b4995
+        .quad   0xe027b34f1bad0249
+        .quad   0x7bc92fc9b9fa74ed
+        .quad   0x9f97ef2e801ad9f9
+        .quad   0x83697d5479afda3a
+        .quad   0xe906b3ffbd596b50
+        .quad   0x02672b37dd3fb8e0
+
+        // 2^140 * 2 * B
+
+        .quad   0x48b2ca8b260885e4
+        .quad   0xa4286bec82b34c1c
+        .quad   0x937e1a2617f58f74
+        .quad   0x741d1fcbab2ca2a5
+        .quad   0xee9ba729398ca7f5
+        .quad   0xeb9ca6257a4849db
+        .quad   0x29eb29ce7ec544e1
+        .quad   0x232ca21ef736e2c8
+        .quad   0xbf61423d253fcb17
+        .quad   0x08803ceafa39eb14
+        .quad   0xf18602df9851c7af
+        .quad   0x0400f3a049e3414b
+
+        // 2^140 * 3 * B
+
+        .quad   0xabce0476ba61c55b
+        .quad   0x36a3d6d7c4d39716
+        .quad   0x6eb259d5e8d82d09
+        .quad   0x0c9176e984d756fb
+        .quad   0x2efba412a06e7b06
+        .quad   0x146785452c8d2560
+        .quad   0xdf9713ebd67a91c7
+        .quad   0x32830ac7157eadf3
+        .quad   0x0e782a7ab73769e8
+        .quad   0x04a05d7875b18e2c
+        .quad   0x29525226ebcceae1
+        .quad   0x0d794f8383eba820
+
+        // 2^140 * 4 * B
+
+        .quad   0xff35f5cb9e1516f4
+        .quad   0xee805bcf648aae45
+        .quad   0xf0d73c2bb93a9ef3
+        .quad   0x097b0bf22092a6c2
+        .quad   0x7be44ce7a7a2e1ac
+        .quad   0x411fd93efad1b8b7
+        .quad   0x1734a1d70d5f7c9b
+        .quad   0x0d6592233127db16
+        .quad   0xc48bab1521a9d733
+        .quad   0xa6c2eaead61abb25
+        .quad   0x625c6c1cc6cb4305
+        .quad   0x7fc90fea93eb3a67
+
+        // 2^140 * 5 * B
+
+        .quad   0x0408f1fe1f5c5926
+        .quad   0x1a8f2f5e3b258bf4
+        .quad   0x40a951a2fdc71669
+        .quad   0x6598ee93c98b577e
+        .quad   0xc527deb59c7cb23d
+        .quad   0x955391695328404e
+        .quad   0xd64392817ccf2c7a
+        .quad   0x6ce97dabf7d8fa11
+        .quad   0x25b5a8e50ef7c48f
+        .quad   0xeb6034116f2ce532
+        .quad   0xc5e75173e53de537
+        .quad   0x73119fa08c12bb03
+
+        // 2^140 * 6 * B
+
+        .quad   0xed30129453f1a4cb
+        .quad   0xbce621c9c8f53787
+        .quad   0xfacb2b1338bee7b9
+        .quad   0x3025798a9ea8428c
+        .quad   0x7845b94d21f4774d
+        .quad   0xbf62f16c7897b727
+        .quad   0x671857c03c56522b
+        .quad   0x3cd6a85295621212
+        .quad   0x3fecde923aeca999
+        .quad   0xbdaa5b0062e8c12f
+        .quad   0x67b99dfc96988ade
+        .quad   0x3f52c02852661036
+
+        // 2^140 * 7 * B
+
+        .quad   0xffeaa48e2a1351c6
+        .quad   0x28624754fa7f53d7
+        .quad   0x0b5ba9e57582ddf1
+        .quad   0x60c0104ba696ac59
+        .quad   0x9258bf99eec416c6
+        .quad   0xac8a5017a9d2f671
+        .quad   0x629549ab16dea4ab
+        .quad   0x05d0e85c99091569
+        .quad   0x051de020de9cbe97
+        .quad   0xfa07fc56b50bcf74
+        .quad   0x378cec9f0f11df65
+        .quad   0x36853c69ab96de4d
+
+        // 2^140 * 8 * B
+
+        .quad   0x36d9b8de78f39b2d
+        .quad   0x7f42ed71a847b9ec
+        .quad   0x241cd1d679bd3fde
+        .quad   0x6a704fec92fbce6b
+        .quad   0x4433c0b0fac5e7be
+        .quad   0x724bae854c08dcbe
+        .quad   0xf1f24cc446978f9b
+        .quad   0x4a0aff6d62825fc8
+        .quad   0xe917fb9e61095301
+        .quad   0xc102df9402a092f8
+        .quad   0xbf09e2f5fa66190b
+        .quad   0x681109bee0dcfe37
+
+        // 2^144 * 1 * B
+
+        .quad   0x559a0cc9782a0dde
+        .quad   0x551dcdb2ea718385
+        .quad   0x7f62865b31ef238c
+        .quad   0x504aa7767973613d
+        .quad   0x9c18fcfa36048d13
+        .quad   0x29159db373899ddd
+        .quad   0xdc9f350b9f92d0aa
+        .quad   0x26f57eee878a19d4
+        .quad   0x0cab2cd55687efb1
+        .quad   0x5180d162247af17b
+        .quad   0x85c15a344f5a2467
+        .quad   0x4041943d9dba3069
+
+        // 2^144 * 2 * B
+
+        .quad   0xc3c0eeba43ebcc96
+        .quad   0x8d749c9c26ea9caf
+        .quad   0xd9fa95ee1c77ccc6
+        .quad   0x1420a1d97684340f
+        .quad   0x4b217743a26caadd
+        .quad   0x47a6b424648ab7ce
+        .quad   0xcb1d4f7a03fbc9e3
+        .quad   0x12d931429800d019
+        .quad   0x00c67799d337594f
+        .quad   0x5e3c5140b23aa47b
+        .quad   0x44182854e35ff395
+        .quad   0x1b4f92314359a012
+
+        // 2^144 * 3 * B
+
+        .quad   0x3e5c109d89150951
+        .quad   0x39cefa912de9696a
+        .quad   0x20eae43f975f3020
+        .quad   0x239b572a7f132dae
+        .quad   0x33cf3030a49866b1
+        .quad   0x251f73d2215f4859
+        .quad   0xab82aa4051def4f6
+        .quad   0x5ff191d56f9a23f6
+        .quad   0x819ed433ac2d9068
+        .quad   0x2883ab795fc98523
+        .quad   0xef4572805593eb3d
+        .quad   0x020c526a758f36cb
+
+        // 2^144 * 4 * B
+
+        .quad   0x779834f89ed8dbbc
+        .quad   0xc8f2aaf9dc7ca46c
+        .quad   0xa9524cdca3e1b074
+        .quad   0x02aacc4615313877
+        .quad   0xe931ef59f042cc89
+        .quad   0x2c589c9d8e124bb6
+        .quad   0xadc8e18aaec75997
+        .quad   0x452cfe0a5602c50c
+        .quad   0x86a0f7a0647877df
+        .quad   0xbbc464270e607c9f
+        .quad   0xab17ea25f1fb11c9
+        .quad   0x4cfb7d7b304b877b
+
+        // 2^144 * 5 * B
+
+        .quad   0x72b43d6cb89b75fe
+        .quad   0x54c694d99c6adc80
+        .quad   0xb8c3aa373ee34c9f
+        .quad   0x14b4622b39075364
+        .quad   0xe28699c29789ef12
+        .quad   0x2b6ecd71df57190d
+        .quad   0xc343c857ecc970d0
+        .quad   0x5b1d4cbc434d3ac5
+        .quad   0xb6fb2615cc0a9f26
+        .quad   0x3a4f0e2bb88dcce5
+        .quad   0x1301498b3369a705
+        .quad   0x2f98f71258592dd1
+
+        // 2^144 * 6 * B
+
+        .quad   0x0c94a74cb50f9e56
+        .quad   0x5b1ff4a98e8e1320
+        .quad   0x9a2acc2182300f67
+        .quad   0x3a6ae249d806aaf9
+        .quad   0x2e12ae444f54a701
+        .quad   0xfcfe3ef0a9cbd7de
+        .quad   0xcebf890d75835de0
+        .quad   0x1d8062e9e7614554
+        .quad   0x657ada85a9907c5a
+        .quad   0x1a0ea8b591b90f62
+        .quad   0x8d0e1dfbdf34b4e9
+        .quad   0x298b8ce8aef25ff3
+
+        // 2^144 * 7 * B
+
+        .quad   0x2a927953eff70cb2
+        .quad   0x4b89c92a79157076
+        .quad   0x9418457a30a7cf6a
+        .quad   0x34b8a8404d5ce485
+        .quad   0x837a72ea0a2165de
+        .quad   0x3fab07b40bcf79f6
+        .quad   0x521636c77738ae70
+        .quad   0x6ba6271803a7d7dc
+        .quad   0xc26eecb583693335
+        .quad   0xd5a813df63b5fefd
+        .quad   0xa293aa9aa4b22573
+        .quad   0x71d62bdd465e1c6a
+
+        // 2^144 * 8 * B
+
+        .quad   0x6533cc28d378df80
+        .quad   0xf6db43790a0fa4b4
+        .quad   0xe3645ff9f701da5a
+        .quad   0x74d5f317f3172ba4
+        .quad   0xcd2db5dab1f75ef5
+        .quad   0xd77f95cf16b065f5
+        .quad   0x14571fea3f49f085
+        .quad   0x1c333621262b2b3d
+        .quad   0xa86fe55467d9ca81
+        .quad   0x398b7c752b298c37
+        .quad   0xda6d0892e3ac623b
+        .quad   0x4aebcc4547e9d98c
+
+        // 2^148 * 1 * B
+
+        .quad   0x53175a7205d21a77
+        .quad   0xb0c04422d3b934d4
+        .quad   0xadd9f24bdd5deadc
+        .quad   0x074f46e69f10ff8c
+        .quad   0x0de9b204a059a445
+        .quad   0xe15cb4aa4b17ad0f
+        .quad   0xe1bbec521f79c557
+        .quad   0x2633f1b9d071081b
+        .quad   0xc1fb4177018b9910
+        .quad   0xa6ea20dc6c0fe140
+        .quad   0xd661f3e74354c6ff
+        .quad   0x5ecb72e6f1a3407a
+
+        // 2^148 * 2 * B
+
+        .quad   0xa515a31b2259fb4e
+        .quad   0x0960f3972bcac52f
+        .quad   0xedb52fec8d3454cb
+        .quad   0x382e2720c476c019
+        .quad   0xfeeae106e8e86997
+        .quad   0x9863337f98d09383
+        .quad   0x9470480eaa06ebef
+        .quad   0x038b6898d4c5c2d0
+        .quad   0xf391c51d8ace50a6
+        .quad   0x3142d0b9ae2d2948
+        .quad   0xdb4d5a1a7f24ca80
+        .quad   0x21aeba8b59250ea8
+
+        // 2^148 * 3 * B
+
+        .quad   0x24f13b34cf405530
+        .quad   0x3c44ea4a43088af7
+        .quad   0x5dd5c5170006a482
+        .quad   0x118eb8f8890b086d
+        .quad   0x53853600f0087f23
+        .quad   0x4c461879da7d5784
+        .quad   0x6af303deb41f6860
+        .quad   0x0a3c16c5c27c18ed
+        .quad   0x17e49c17cc947f3d
+        .quad   0xccc6eda6aac1d27b
+        .quad   0xdf6092ceb0f08e56
+        .quad   0x4909b3e22c67c36b
+
+        // 2^148 * 4 * B
+
+        .quad   0x9c9c85ea63fe2e89
+        .quad   0xbe1baf910e9412ec
+        .quad   0x8f7baa8a86fbfe7b
+        .quad   0x0fb17f9fef968b6c
+        .quad   0x59a16676706ff64e
+        .quad   0x10b953dd0d86a53d
+        .quad   0x5848e1e6ce5c0b96
+        .quad   0x2d8b78e712780c68
+        .quad   0x79d5c62eafc3902b
+        .quad   0x773a215289e80728
+        .quad   0xc38ae640e10120b9
+        .quad   0x09ae23717b2b1a6d
+
+        // 2^148 * 5 * B
+
+        .quad   0xbb6a192a4e4d083c
+        .quad   0x34ace0630029e192
+        .quad   0x98245a59aafabaeb
+        .quad   0x6d9c8a9ada97faac
+        .quad   0x10ab8fa1ad32b1d0
+        .quad   0xe9aced1be2778b24
+        .quad   0xa8856bc0373de90f
+        .quad   0x66f35ddddda53996
+        .quad   0xd27d9afb24997323
+        .quad   0x1bb7e07ef6f01d2e
+        .quad   0x2ba7472df52ecc7f
+        .quad   0x03019b4f646f9dc8
+
+        // 2^148 * 6 * B
+
+        .quad   0x04a186b5565345cd
+        .quad   0xeee76610bcc4116a
+        .quad   0x689c73b478fb2a45
+        .quad   0x387dcbff65697512
+        .quad   0xaf09b214e6b3dc6b
+        .quad   0x3f7573b5ad7d2f65
+        .quad   0xd019d988100a23b0
+        .quad   0x392b63a58b5c35f7
+        .quad   0x4093addc9c07c205
+        .quad   0xc565be15f532c37e
+        .quad   0x63dbecfd1583402a
+        .quad   0x61722b4aef2e032e
+
+        // 2^148 * 7 * B
+
+        .quad   0x0012aafeecbd47af
+        .quad   0x55a266fb1cd46309
+        .quad   0xf203eb680967c72c
+        .quad   0x39633944ca3c1429
+        .quad   0xd6b07a5581cb0e3c
+        .quad   0x290ff006d9444969
+        .quad   0x08680b6a16dcda1f
+        .quad   0x5568d2b75a06de59
+        .quad   0x8d0cb88c1b37cfe1
+        .quad   0x05b6a5a3053818f3
+        .quad   0xf2e9bc04b787d959
+        .quad   0x6beba1249add7f64
+
+        // 2^148 * 8 * B
+
+        .quad   0x1d06005ca5b1b143
+        .quad   0x6d4c6bb87fd1cda2
+        .quad   0x6ef5967653fcffe7
+        .quad   0x097c29e8c1ce1ea5
+        .quad   0x5c3cecb943f5a53b
+        .quad   0x9cc9a61d06c08df2
+        .quad   0xcfba639a85895447
+        .quad   0x5a845ae80df09fd5
+        .quad   0x4ce97dbe5deb94ca
+        .quad   0x38d0a4388c709c48
+        .quad   0xc43eced4a169d097
+        .quad   0x0a1249fff7e587c3
+
+        // 2^152 * 1 * B
+
+        .quad   0x12f0071b276d01c9
+        .quad   0xe7b8bac586c48c70
+        .quad   0x5308129b71d6fba9
+        .quad   0x5d88fbf95a3db792
+        .quad   0x0b408d9e7354b610
+        .quad   0x806b32535ba85b6e
+        .quad   0xdbe63a034a58a207
+        .quad   0x173bd9ddc9a1df2c
+        .quad   0x2b500f1efe5872df
+        .quad   0x58d6582ed43918c1
+        .quad   0xe6ed278ec9673ae0
+        .quad   0x06e1cd13b19ea319
+
+        // 2^152 * 2 * B
+
+        .quad   0x40d0ad516f166f23
+        .quad   0x118e32931fab6abe
+        .quad   0x3fe35e14a04d088e
+        .quad   0x3080603526e16266
+        .quad   0x472baf629e5b0353
+        .quad   0x3baa0b90278d0447
+        .quad   0x0c785f469643bf27
+        .quad   0x7f3a6a1a8d837b13
+        .quad   0xf7e644395d3d800b
+        .quad   0x95a8d555c901edf6
+        .quad   0x68cd7830592c6339
+        .quad   0x30d0fded2e51307e
+
+        // 2^152 * 3 * B
+
+        .quad   0xe0594d1af21233b3
+        .quad   0x1bdbe78ef0cc4d9c
+        .quad   0x6965187f8f499a77
+        .quad   0x0a9214202c099868
+        .quad   0x9cb4971e68b84750
+        .quad   0xa09572296664bbcf
+        .quad   0x5c8de72672fa412b
+        .quad   0x4615084351c589d9
+        .quad   0xbc9019c0aeb9a02e
+        .quad   0x55c7110d16034cae
+        .quad   0x0e6df501659932ec
+        .quad   0x3bca0d2895ca5dfe
+
+        // 2^152 * 4 * B
+
+        .quad   0x40f031bc3c5d62a4
+        .quad   0x19fc8b3ecff07a60
+        .quad   0x98183da2130fb545
+        .quad   0x5631deddae8f13cd
+        .quad   0x9c688eb69ecc01bf
+        .quad   0xf0bc83ada644896f
+        .quad   0xca2d955f5f7a9fe2
+        .quad   0x4ea8b4038df28241
+        .quad   0x2aed460af1cad202
+        .quad   0x46305305a48cee83
+        .quad   0x9121774549f11a5f
+        .quad   0x24ce0930542ca463
+
+        // 2^152 * 5 * B
+
+        .quad   0x1fe890f5fd06c106
+        .quad   0xb5c468355d8810f2
+        .quad   0x827808fe6e8caf3e
+        .quad   0x41d4e3c28a06d74b
+        .quad   0x3fcfa155fdf30b85
+        .quad   0xd2f7168e36372ea4
+        .quad   0xb2e064de6492f844
+        .quad   0x549928a7324f4280
+        .quad   0xf26e32a763ee1a2e
+        .quad   0xae91e4b7d25ffdea
+        .quad   0xbc3bd33bd17f4d69
+        .quad   0x491b66dec0dcff6a
+
+        // 2^152 * 6 * B
+
+        .quad   0x98f5b13dc7ea32a7
+        .quad   0xe3d5f8cc7e16db98
+        .quad   0xac0abf52cbf8d947
+        .quad   0x08f338d0c85ee4ac
+        .quad   0x75f04a8ed0da64a1
+        .quad   0xed222caf67e2284b
+        .quad   0x8234a3791f7b7ba4
+        .quad   0x4cf6b8b0b7018b67
+        .quad   0xc383a821991a73bd
+        .quad   0xab27bc01df320c7a
+        .quad   0xc13d331b84777063
+        .quad   0x530d4a82eb078a99
+
+        // 2^152 * 7 * B
+
+        .quad   0x004c3630e1f94825
+        .quad   0x7e2d78268cab535a
+        .quad   0xc7482323cc84ff8b
+        .quad   0x65ea753f101770b9
+        .quad   0x6d6973456c9abf9e
+        .quad   0x257fb2fc4900a880
+        .quad   0x2bacf412c8cfb850
+        .quad   0x0db3e7e00cbfbd5b
+        .quad   0x3d66fc3ee2096363
+        .quad   0x81d62c7f61b5cb6b
+        .quad   0x0fbe044213443b1a
+        .quad   0x02a4ec1921e1a1db
+
+        // 2^152 * 8 * B
+
+        .quad   0x5ce6259a3b24b8a2
+        .quad   0xb8577acc45afa0b8
+        .quad   0xcccbe6e88ba07037
+        .quad   0x3d143c51127809bf
+        .quad   0xf5c86162f1cf795f
+        .quad   0x118c861926ee57f2
+        .quad   0x172124851c063578
+        .quad   0x36d12b5dec067fcf
+        .quad   0x126d279179154557
+        .quad   0xd5e48f5cfc783a0a
+        .quad   0x36bdb6e8df179bac
+        .quad   0x2ef517885ba82859
+
+        // 2^156 * 1 * B
+
+        .quad   0x88bd438cd11e0d4a
+        .quad   0x30cb610d43ccf308
+        .quad   0xe09a0e3791937bcc
+        .quad   0x4559135b25b1720c
+        .quad   0x1ea436837c6da1e9
+        .quad   0xf9c189af1fb9bdbe
+        .quad   0x303001fcce5dd155
+        .quad   0x28a7c99ebc57be52
+        .quad   0xb8fd9399e8d19e9d
+        .quad   0x908191cb962423ff
+        .quad   0xb2b948d747c742a3
+        .quad   0x37f33226d7fb44c4
+
+        // 2^156 * 2 * B
+
+        .quad   0x0dae8767b55f6e08
+        .quad   0x4a43b3b35b203a02
+        .quad   0xe3725a6e80af8c79
+        .quad   0x0f7a7fd1705fa7a3
+        .quad   0x33912553c821b11d
+        .quad   0x66ed42c241e301df
+        .quad   0x066fcc11104222fd
+        .quad   0x307a3b41c192168f
+        .quad   0x8eeb5d076eb55ce0
+        .quad   0x2fc536bfaa0d925a
+        .quad   0xbe81830fdcb6c6e8
+        .quad   0x556c7045827baf52
+
+        // 2^156 * 3 * B
+
+        .quad   0x8e2b517302e9d8b7
+        .quad   0xe3e52269248714e8
+        .quad   0xbd4fbd774ca960b5
+        .quad   0x6f4b4199c5ecada9
+        .quad   0xb94b90022bf44406
+        .quad   0xabd4237eff90b534
+        .quad   0x7600a960faf86d3a
+        .quad   0x2f45abdac2322ee3
+        .quad   0x61af4912c8ef8a6a
+        .quad   0xe58fa4fe43fb6e5e
+        .quad   0xb5afcc5d6fd427cf
+        .quad   0x6a5393281e1e11eb
+
+        // 2^156 * 4 * B
+
+        .quad   0xf3da5139a5d1ee89
+        .quad   0x8145457cff936988
+        .quad   0x3f622fed00e188c4
+        .quad   0x0f513815db8b5a3d
+        .quad   0x0fff04fe149443cf
+        .quad   0x53cac6d9865cddd7
+        .quad   0x31385b03531ed1b7
+        .quad   0x5846a27cacd1039d
+        .quad   0x4ff5cdac1eb08717
+        .quad   0x67e8b29590f2e9bc
+        .quad   0x44093b5e237afa99
+        .quad   0x0d414bed8708b8b2
+
+        // 2^156 * 5 * B
+
+        .quad   0xcfb68265fd0e75f6
+        .quad   0xe45b3e28bb90e707
+        .quad   0x7242a8de9ff92c7a
+        .quad   0x685b3201933202dd
+        .quad   0x81886a92294ac9e8
+        .quad   0x23162b45d55547be
+        .quad   0x94cfbc4403715983
+        .quad   0x50eb8fdb134bc401
+        .quad   0xc0b73ec6d6b330cd
+        .quad   0x84e44807132faff1
+        .quad   0x732b7352c4a5dee1
+        .quad   0x5d7c7cf1aa7cd2d2
+
+        // 2^156 * 6 * B
+
+        .quad   0xaf3b46bf7a4aafa2
+        .quad   0xb78705ec4d40d411
+        .quad   0x114f0c6aca7c15e3
+        .quad   0x3f364faaa9489d4d
+        .quad   0x33d1013e9b73a562
+        .quad   0x925cef5748ec26e1
+        .quad   0xa7fce614dd468058
+        .quad   0x78b0fad41e9aa438
+        .quad   0xbf56a431ed05b488
+        .quad   0xa533e66c9c495c7e
+        .quad   0xe8652baf87f3651a
+        .quad   0x0241800059d66c33
+
+        // 2^156 * 7 * B
+
+        .quad   0xceb077fea37a5be4
+        .quad   0xdb642f02e5a5eeb7
+        .quad   0xc2e6d0c5471270b8
+        .quad   0x4771b65538e4529c
+        .quad   0x28350c7dcf38ea01
+        .quad   0x7c6cdbc0b2917ab6
+        .quad   0xace7cfbe857082f7
+        .quad   0x4d2845aba2d9a1e0
+        .quad   0xbb537fe0447070de
+        .quad   0xcba744436dd557df
+        .quad   0xd3b5a3473600dbcb
+        .quad   0x4aeabbe6f9ffd7f8
+
+        // 2^156 * 8 * B
+
+        .quad   0x4630119e40d8f78c
+        .quad   0xa01a9bc53c710e11
+        .quad   0x486d2b258910dd79
+        .quad   0x1e6c47b3db0324e5
+        .quad   0x6a2134bcc4a9c8f2
+        .quad   0xfbf8fd1c8ace2e37
+        .quad   0x000ae3049911a0ba
+        .quad   0x046e3a616bc89b9e
+        .quad   0x14e65442f03906be
+        .quad   0x4a019d54e362be2a
+        .quad   0x68ccdfec8dc230c7
+        .quad   0x7cfb7e3faf6b861c
+
+        // 2^160 * 1 * B
+
+        .quad   0x4637974e8c58aedc
+        .quad   0xb9ef22fbabf041a4
+        .quad   0xe185d956e980718a
+        .quad   0x2f1b78fab143a8a6
+        .quad   0x96eebffb305b2f51
+        .quad   0xd3f938ad889596b8
+        .quad   0xf0f52dc746d5dd25
+        .quad   0x57968290bb3a0095
+        .quad   0xf71ab8430a20e101
+        .quad   0xf393658d24f0ec47
+        .quad   0xcf7509a86ee2eed1
+        .quad   0x7dc43e35dc2aa3e1
+
+        // 2^160 * 2 * B
+
+        .quad   0x85966665887dd9c3
+        .quad   0xc90f9b314bb05355
+        .quad   0xc6e08df8ef2079b1
+        .quad   0x7ef72016758cc12f
+        .quad   0x5a782a5c273e9718
+        .quad   0x3576c6995e4efd94
+        .quad   0x0f2ed8051f237d3e
+        .quad   0x044fb81d82d50a99
+        .quad   0xc1df18c5a907e3d9
+        .quad   0x57b3371dce4c6359
+        .quad   0xca704534b201bb49
+        .quad   0x7f79823f9c30dd2e
+
+        // 2^160 * 3 * B
+
+        .quad   0x8334d239a3b513e8
+        .quad   0xc13670d4b91fa8d8
+        .quad   0x12b54136f590bd33
+        .quad   0x0a4e0373d784d9b4
+        .quad   0x6a9c1ff068f587ba
+        .quad   0x0827894e0050c8de
+        .quad   0x3cbf99557ded5be7
+        .quad   0x64a9b0431c06d6f0
+        .quad   0x2eb3d6a15b7d2919
+        .quad   0xb0b4f6a0d53a8235
+        .quad   0x7156ce4389a45d47
+        .quad   0x071a7d0ace18346c
+
+        // 2^160 * 4 * B
+
+        .quad   0xd3072daac887ba0b
+        .quad   0x01262905bfa562ee
+        .quad   0xcf543002c0ef768b
+        .quad   0x2c3bcc7146ea7e9c
+        .quad   0xcc0c355220e14431
+        .quad   0x0d65950709b15141
+        .quad   0x9af5621b209d5f36
+        .quad   0x7c69bcf7617755d3
+        .quad   0x07f0d7eb04e8295f
+        .quad   0x10db18252f50f37d
+        .quad   0xe951a9a3171798d7
+        .quad   0x6f5a9a7322aca51d
+
+        // 2^160 * 5 * B
+
+        .quad   0x8ba1000c2f41c6c5
+        .quad   0xc49f79c10cfefb9b
+        .quad   0x4efa47703cc51c9f
+        .quad   0x494e21a2e147afca
+        .quad   0xe729d4eba3d944be
+        .quad   0x8d9e09408078af9e
+        .quad   0x4525567a47869c03
+        .quad   0x02ab9680ee8d3b24
+        .quad   0xefa48a85dde50d9a
+        .quad   0x219a224e0fb9a249
+        .quad   0xfa091f1dd91ef6d9
+        .quad   0x6b5d76cbea46bb34
+
+        // 2^160 * 6 * B
+
+        .quad   0x8857556cec0cd994
+        .quad   0x6472dc6f5cd01dba
+        .quad   0xaf0169148f42b477
+        .quad   0x0ae333f685277354
+        .quad   0xe0f941171e782522
+        .quad   0xf1e6ae74036936d3
+        .quad   0x408b3ea2d0fcc746
+        .quad   0x16fb869c03dd313e
+        .quad   0x288e199733b60962
+        .quad   0x24fc72b4d8abe133
+        .quad   0x4811f7ed0991d03e
+        .quad   0x3f81e38b8f70d075
+
+        // 2^160 * 7 * B
+
+        .quad   0x7f910fcc7ed9affe
+        .quad   0x545cb8a12465874b
+        .quad   0xa8397ed24b0c4704
+        .quad   0x50510fc104f50993
+        .quad   0x0adb7f355f17c824
+        .quad   0x74b923c3d74299a4
+        .quad   0xd57c3e8bcbf8eaf7
+        .quad   0x0ad3e2d34cdedc3d
+        .quad   0x6f0c0fc5336e249d
+        .quad   0x745ede19c331cfd9
+        .quad   0xf2d6fd0009eefe1c
+        .quad   0x127c158bf0fa1ebe
+
+        // 2^160 * 8 * B
+
+        .quad   0xf6197c422e9879a2
+        .quad   0xa44addd452ca3647
+        .quad   0x9b413fc14b4eaccb
+        .quad   0x354ef87d07ef4f68
+        .quad   0xdea28fc4ae51b974
+        .quad   0x1d9973d3744dfe96
+        .quad   0x6240680b873848a8
+        .quad   0x4ed82479d167df95
+        .quad   0xfee3b52260c5d975
+        .quad   0x50352efceb41b0b8
+        .quad   0x8808ac30a9f6653c
+        .quad   0x302d92d20539236d
+
+        // 2^164 * 1 * B
+
+        .quad   0x4c59023fcb3efb7c
+        .quad   0x6c2fcb99c63c2a94
+        .quad   0xba4190e2c3c7e084
+        .quad   0x0e545daea51874d9
+        .quad   0x957b8b8b0df53c30
+        .quad   0x2a1c770a8e60f098
+        .quad   0xbbc7a670345796de
+        .quad   0x22a48f9a90c99bc9
+        .quad   0x6b7dc0dc8d3fac58
+        .quad   0x5497cd6ce6e42bfd
+        .quad   0x542f7d1bf400d305
+        .quad   0x4159f47f048d9136
+
+        // 2^164 * 2 * B
+
+        .quad   0x20ad660839e31e32
+        .quad   0xf81e1bd58405be50
+        .quad   0xf8064056f4dabc69
+        .quad   0x14d23dd4ce71b975
+        .quad   0x748515a8bbd24839
+        .quad   0x77128347afb02b55
+        .quad   0x50ba2ac649a2a17f
+        .quad   0x060525513ad730f1
+        .quad   0xf2398e098aa27f82
+        .quad   0x6d7982bb89a1b024
+        .quad   0xfa694084214dd24c
+        .quad   0x71ab966fa32301c3
+
+        // 2^164 * 3 * B
+
+        .quad   0x2dcbd8e34ded02fc
+        .quad   0x1151f3ec596f22aa
+        .quad   0xbca255434e0328da
+        .quad   0x35768fbe92411b22
+        .quad   0xb1088a0702809955
+        .quad   0x43b273ea0b43c391
+        .quad   0xca9b67aefe0686ed
+        .quad   0x605eecbf8335f4ed
+        .quad   0x83200a656c340431
+        .quad   0x9fcd71678ee59c2f
+        .quad   0x75d4613f71300f8a
+        .quad   0x7a912faf60f542f9
+
+        // 2^164 * 4 * B
+
+        .quad   0xb204585e5edc1a43
+        .quad   0x9f0e16ee5897c73c
+        .quad   0x5b82c0ae4e70483c
+        .quad   0x624a170e2bddf9be
+        .quad   0x253f4f8dfa2d5597
+        .quad   0x25e49c405477130c
+        .quad   0x00c052e5996b1102
+        .quad   0x33cb966e33bb6c4a
+        .quad   0x597028047f116909
+        .quad   0x828ac41c1e564467
+        .quad   0x70417dbde6217387
+        .quad   0x721627aefbac4384
+
+        // 2^164 * 5 * B
+
+        .quad   0x97d03bc38736add5
+        .quad   0x2f1422afc532b130
+        .quad   0x3aa68a057101bbc4
+        .quad   0x4c946cf7e74f9fa7
+        .quad   0xfd3097bc410b2f22
+        .quad   0xf1a05da7b5cfa844
+        .quad   0x61289a1def57ca74
+        .quad   0x245ea199bb821902
+        .quad   0xaedca66978d477f8
+        .quad   0x1898ba3c29117fe1
+        .quad   0xcf73f983720cbd58
+        .quad   0x67da12e6b8b56351
+
+        // 2^164 * 6 * B
+
+        .quad   0x7067e187b4bd6e07
+        .quad   0x6e8f0203c7d1fe74
+        .quad   0x93c6aa2f38c85a30
+        .quad   0x76297d1f3d75a78a
+        .quad   0x2b7ef3d38ec8308c
+        .quad   0x828fd7ec71eb94ab
+        .quad   0x807c3b36c5062abd
+        .quad   0x0cb64cb831a94141
+        .quad   0x3030fc33534c6378
+        .quad   0xb9635c5ce541e861
+        .quad   0x15d9a9bed9b2c728
+        .quad   0x49233ea3f3775dcb
+
+        // 2^164 * 7 * B
+
+        .quad   0x629398fa8dbffc3a
+        .quad   0xe12fe52dd54db455
+        .quad   0xf3be11dfdaf25295
+        .quad   0x628b140dce5e7b51
+        .quad   0x7b3985fe1c9f249b
+        .quad   0x4fd6b2d5a1233293
+        .quad   0xceb345941adf4d62
+        .quad   0x6987ff6f542de50c
+        .quad   0x47e241428f83753c
+        .quad   0x6317bebc866af997
+        .quad   0xdabb5b433d1a9829
+        .quad   0x074d8d245287fb2d
+
+        // 2^164 * 8 * B
+
+        .quad   0x8337d9cd440bfc31
+        .quad   0x729d2ca1af318fd7
+        .quad   0xa040a4a4772c2070
+        .quad   0x46002ef03a7349be
+        .quad   0x481875c6c0e31488
+        .quad   0x219429b2e22034b4
+        .quad   0x7223c98a31283b65
+        .quad   0x3420d60b342277f9
+        .quad   0xfaa23adeaffe65f7
+        .quad   0x78261ed45be0764c
+        .quad   0x441c0a1e2f164403
+        .quad   0x5aea8e567a87d395
+
+        // 2^168 * 1 * B
+
+        .quad   0x7813c1a2bca4283d
+        .quad   0xed62f091a1863dd9
+        .quad   0xaec7bcb8c268fa86
+        .quad   0x10e5d3b76f1cae4c
+        .quad   0x2dbc6fb6e4e0f177
+        .quad   0x04e1bf29a4bd6a93
+        .quad   0x5e1966d4787af6e8
+        .quad   0x0edc5f5eb426d060
+        .quad   0x5453bfd653da8e67
+        .quad   0xe9dc1eec24a9f641
+        .quad   0xbf87263b03578a23
+        .quad   0x45b46c51361cba72
+
+        // 2^168 * 2 * B
+
+        .quad   0xa9402abf314f7fa1
+        .quad   0xe257f1dc8e8cf450
+        .quad   0x1dbbd54b23a8be84
+        .quad   0x2177bfa36dcb713b
+        .quad   0xce9d4ddd8a7fe3e4
+        .quad   0xab13645676620e30
+        .quad   0x4b594f7bb30e9958
+        .quad   0x5c1c0aef321229df
+        .quad   0x37081bbcfa79db8f
+        .quad   0x6048811ec25f59b3
+        .quad   0x087a76659c832487
+        .quad   0x4ae619387d8ab5bb
+
+        // 2^168 * 3 * B
+
+        .quad   0x8ddbf6aa5344a32e
+        .quad   0x7d88eab4b41b4078
+        .quad   0x5eb0eb974a130d60
+        .quad   0x1a00d91b17bf3e03
+        .quad   0x61117e44985bfb83
+        .quad   0xfce0462a71963136
+        .quad   0x83ac3448d425904b
+        .quad   0x75685abe5ba43d64
+        .quad   0x6e960933eb61f2b2
+        .quad   0x543d0fa8c9ff4952
+        .quad   0xdf7275107af66569
+        .quad   0x135529b623b0e6aa
+
+        // 2^168 * 4 * B
+
+        .quad   0x18f0dbd7add1d518
+        .quad   0x979f7888cfc11f11
+        .quad   0x8732e1f07114759b
+        .quad   0x79b5b81a65ca3a01
+        .quad   0xf5c716bce22e83fe
+        .quad   0xb42beb19e80985c1
+        .quad   0xec9da63714254aae
+        .quad   0x5972ea051590a613
+        .quad   0x0fd4ac20dc8f7811
+        .quad   0x9a9ad294ac4d4fa8
+        .quad   0xc01b2d64b3360434
+        .quad   0x4f7e9c95905f3bdb
+
+        // 2^168 * 5 * B
+
+        .quad   0x62674bbc5781302e
+        .quad   0xd8520f3989addc0f
+        .quad   0x8c2999ae53fbd9c6
+        .quad   0x31993ad92e638e4c
+        .quad   0x71c8443d355299fe
+        .quad   0x8bcd3b1cdbebead7
+        .quad   0x8092499ef1a49466
+        .quad   0x1942eec4a144adc8
+        .quad   0x7dac5319ae234992
+        .quad   0x2c1b3d910cea3e92
+        .quad   0x553ce494253c1122
+        .quad   0x2a0a65314ef9ca75
+
+        // 2^168 * 6 * B
+
+        .quad   0x2db7937ff7f927c2
+        .quad   0xdb741f0617d0a635
+        .quad   0x5982f3a21155af76
+        .quad   0x4cf6e218647c2ded
+        .quad   0xcf361acd3c1c793a
+        .quad   0x2f9ebcac5a35bc3b
+        .quad   0x60e860e9a8cda6ab
+        .quad   0x055dc39b6dea1a13
+        .quad   0xb119227cc28d5bb6
+        .quad   0x07e24ebc774dffab
+        .quad   0xa83c78cee4a32c89
+        .quad   0x121a307710aa24b6
+
+        // 2^168 * 7 * B
+
+        .quad   0xe4db5d5e9f034a97
+        .quad   0xe153fc093034bc2d
+        .quad   0x460546919551d3b1
+        .quad   0x333fc76c7a40e52d
+        .quad   0xd659713ec77483c9
+        .quad   0x88bfe077b82b96af
+        .quad   0x289e28231097bcd3
+        .quad   0x527bb94a6ced3a9b
+        .quad   0x563d992a995b482e
+        .quad   0x3405d07c6e383801
+        .quad   0x485035de2f64d8e5
+        .quad   0x6b89069b20a7a9f7
+
+        // 2^168 * 8 * B
+
+        .quad   0x812aa0416270220d
+        .quad   0x995a89faf9245b4e
+        .quad   0xffadc4ce5072ef05
+        .quad   0x23bc2103aa73eb73
+        .quad   0x4082fa8cb5c7db77
+        .quad   0x068686f8c734c155
+        .quad   0x29e6c8d9f6e7a57e
+        .quad   0x0473d308a7639bcf
+        .quad   0xcaee792603589e05
+        .quad   0x2b4b421246dcc492
+        .quad   0x02a1ef74e601a94f
+        .quad   0x102f73bfde04341a
+
+        // 2^172 * 1 * B
+
+        .quad   0xb5a2d50c7ec20d3e
+        .quad   0xc64bdd6ea0c97263
+        .quad   0x56e89052c1ff734d
+        .quad   0x4929c6f72b2ffaba
+        .quad   0x358ecba293a36247
+        .quad   0xaf8f9862b268fd65
+        .quad   0x412f7e9968a01c89
+        .quad   0x5786f312cd754524
+        .quad   0x337788ffca14032c
+        .quad   0xf3921028447f1ee3
+        .quad   0x8b14071f231bccad
+        .quad   0x4c817b4bf2344783
+
+        // 2^172 * 2 * B
+
+        .quad   0x0ff853852871b96e
+        .quad   0xe13e9fab60c3f1bb
+        .quad   0xeefd595325344402
+        .quad   0x0a37c37075b7744b
+        .quad   0x413ba057a40b4484
+        .quad   0xba4c2e1a4f5f6a43
+        .quad   0x614ba0a5aee1d61c
+        .quad   0x78a1531a8b05dc53
+        .quad   0x6cbdf1703ad0562b
+        .quad   0x8ecf4830c92521a3
+        .quad   0xdaebd303fd8424e7
+        .quad   0x72ad82a42e5ec56f
+
+        // 2^172 * 3 * B
+
+        .quad   0x3f9e8e35bafb65f6
+        .quad   0x39d69ec8f27293a1
+        .quad   0x6cb8cd958cf6a3d0
+        .quad   0x1734778173adae6d
+        .quad   0xc368939167024bc3
+        .quad   0x8e69d16d49502fda
+        .quad   0xfcf2ec3ce45f4b29
+        .quad   0x065f669ea3b4cbc4
+        .quad   0x8a00aec75532db4d
+        .quad   0xb869a4e443e31bb1
+        .quad   0x4a0f8552d3a7f515
+        .quad   0x19adeb7c303d7c08
+
+        // 2^172 * 4 * B
+
+        .quad   0xc720cb6153ead9a3
+        .quad   0x55b2c97f512b636e
+        .quad   0xb1e35b5fd40290b1
+        .quad   0x2fd9ccf13b530ee2
+        .quad   0x9d05ba7d43c31794
+        .quad   0x2470c8ff93322526
+        .quad   0x8323dec816197438
+        .quad   0x2852709881569b53
+        .quad   0x07bd475b47f796b8
+        .quad   0xd2c7b013542c8f54
+        .quad   0x2dbd23f43b24f87e
+        .quad   0x6551afd77b0901d6
+
+        // 2^172 * 5 * B
+
+        .quad   0x4546baaf54aac27f
+        .quad   0xf6f66fecb2a45a28
+        .quad   0x582d1b5b562bcfe8
+        .quad   0x44b123f3920f785f
+        .quad   0x68a24ce3a1d5c9ac
+        .quad   0xbb77a33d10ff6461
+        .quad   0x0f86ce4425d3166e
+        .quad   0x56507c0950b9623b
+        .quad   0x1206f0b7d1713e63
+        .quad   0x353fe3d915bafc74
+        .quad   0x194ceb970ad9d94d
+        .quad   0x62fadd7cf9d03ad3
+
+        // 2^172 * 6 * B
+
+        .quad   0xc6b5967b5598a074
+        .quad   0x5efe91ce8e493e25
+        .quad   0xd4b72c4549280888
+        .quad   0x20ef1149a26740c2
+        .quad   0x3cd7bc61e7ce4594
+        .quad   0xcd6b35a9b7dd267e
+        .quad   0xa080abc84366ef27
+        .quad   0x6ec7c46f59c79711
+        .quad   0x2f07ad636f09a8a2
+        .quad   0x8697e6ce24205e7d
+        .quad   0xc0aefc05ee35a139
+        .quad   0x15e80958b5f9d897
+
+        // 2^172 * 7 * B
+
+        .quad   0x25a5ef7d0c3e235b
+        .quad   0x6c39c17fbe134ee7
+        .quad   0xc774e1342dc5c327
+        .quad   0x021354b892021f39
+        .quad   0x4dd1ed355bb061c4
+        .quad   0x42dc0cef941c0700
+        .quad   0x61305dc1fd86340e
+        .quad   0x56b2cc930e55a443
+        .quad   0x1df79da6a6bfc5a2
+        .quad   0x02f3a2749fde4369
+        .quad   0xb323d9f2cda390a7
+        .quad   0x7be0847b8774d363
+
+        // 2^172 * 8 * B
+
+        .quad   0x8c99cc5a8b3f55c3
+        .quad   0x0611d7253fded2a0
+        .quad   0xed2995ff36b70a36
+        .quad   0x1f699a54d78a2619
+        .quad   0x1466f5af5307fa11
+        .quad   0x817fcc7ded6c0af2
+        .quad   0x0a6de44ec3a4a3fb
+        .quad   0x74071475bc927d0b
+        .quad   0xe77292f373e7ea8a
+        .quad   0x296537d2cb045a31
+        .quad   0x1bd0653ed3274fde
+        .quad   0x2f9a2c4476bd2966
+
+        // 2^176 * 1 * B
+
+        .quad   0xeb18b9ab7f5745c6
+        .quad   0x023a8aee5787c690
+        .quad   0xb72712da2df7afa9
+        .quad   0x36597d25ea5c013d
+        .quad   0xa2b4dae0b5511c9a
+        .quad   0x7ac860292bffff06
+        .quad   0x981f375df5504234
+        .quad   0x3f6bd725da4ea12d
+        .quad   0x734d8d7b106058ac
+        .quad   0xd940579e6fc6905f
+        .quad   0x6466f8f99202932d
+        .quad   0x7b7ecc19da60d6d0
+
+        // 2^176 * 2 * B
+
+        .quad   0x78c2373c695c690d
+        .quad   0xdd252e660642906e
+        .quad   0x951d44444ae12bd2
+        .quad   0x4235ad7601743956
+        .quad   0x6dae4a51a77cfa9b
+        .quad   0x82263654e7a38650
+        .quad   0x09bbffcd8f2d82db
+        .quad   0x03bedc661bf5caba
+        .quad   0x6258cb0d078975f5
+        .quad   0x492942549189f298
+        .quad   0xa0cab423e2e36ee4
+        .quad   0x0e7ce2b0cdf066a1
+
+        // 2^176 * 3 * B
+
+        .quad   0xc494643ac48c85a3
+        .quad   0xfd361df43c6139ad
+        .quad   0x09db17dd3ae94d48
+        .quad   0x666e0a5d8fb4674a
+        .quad   0xfea6fedfd94b70f9
+        .quad   0xf130c051c1fcba2d
+        .quad   0x4882d47e7f2fab89
+        .quad   0x615256138aeceeb5
+        .quad   0x2abbf64e4870cb0d
+        .quad   0xcd65bcf0aa458b6b
+        .quad   0x9abe4eba75e8985d
+        .quad   0x7f0bc810d514dee4
+
+        // 2^176 * 4 * B
+
+        .quad   0xb9006ba426f4136f
+        .quad   0x8d67369e57e03035
+        .quad   0xcbc8dfd94f463c28
+        .quad   0x0d1f8dbcf8eedbf5
+        .quad   0x83ac9dad737213a0
+        .quad   0x9ff6f8ba2ef72e98
+        .quad   0x311e2edd43ec6957
+        .quad   0x1d3a907ddec5ab75
+        .quad   0xba1693313ed081dc
+        .quad   0x29329fad851b3480
+        .quad   0x0128013c030321cb
+        .quad   0x00011b44a31bfde3
+
+        // 2^176 * 5 * B
+
+        .quad   0x3fdfa06c3fc66c0c
+        .quad   0x5d40e38e4dd60dd2
+        .quad   0x7ae38b38268e4d71
+        .quad   0x3ac48d916e8357e1
+        .quad   0x16561f696a0aa75c
+        .quad   0xc1bf725c5852bd6a
+        .quad   0x11a8dd7f9a7966ad
+        .quad   0x63d988a2d2851026
+        .quad   0x00120753afbd232e
+        .quad   0xe92bceb8fdd8f683
+        .quad   0xf81669b384e72b91
+        .quad   0x33fad52b2368a066
+
+        // 2^176 * 6 * B
+
+        .quad   0x540649c6c5e41e16
+        .quad   0x0af86430333f7735
+        .quad   0xb2acfcd2f305e746
+        .quad   0x16c0f429a256dca7
+        .quad   0x8d2cc8d0c422cfe8
+        .quad   0x072b4f7b05a13acb
+        .quad   0xa3feb6e6ecf6a56f
+        .quad   0x3cc355ccb90a71e2
+        .quad   0xe9b69443903e9131
+        .quad   0xb8a494cb7a5637ce
+        .quad   0xc87cd1a4baba9244
+        .quad   0x631eaf426bae7568
+
+        // 2^176 * 7 * B
+
+        .quad   0xb3e90410da66fe9f
+        .quad   0x85dd4b526c16e5a6
+        .quad   0xbc3d97611ef9bf83
+        .quad   0x5599648b1ea919b5
+        .quad   0x47d975b9a3700de8
+        .quad   0x7280c5fbe2f80552
+        .quad   0x53658f2732e45de1
+        .quad   0x431f2c7f665f80b5
+        .quad   0xd6026344858f7b19
+        .quad   0x14ab352fa1ea514a
+        .quad   0x8900441a2090a9d7
+        .quad   0x7b04715f91253b26
+
+        // 2^176 * 8 * B
+
+        .quad   0x83edbd28acf6ae43
+        .quad   0x86357c8b7d5c7ab4
+        .quad   0xc0404769b7eb2c44
+        .quad   0x59b37bf5c2f6583f
+        .quad   0xb376c280c4e6bac6
+        .quad   0x970ed3dd6d1d9b0b
+        .quad   0xb09a9558450bf944
+        .quad   0x48d0acfa57cde223
+        .quad   0xb60f26e47dabe671
+        .quad   0xf1d1a197622f3a37
+        .quad   0x4208ce7ee9960394
+        .quad   0x16234191336d3bdb
+
+        // 2^180 * 1 * B
+
+        .quad   0xf19aeac733a63aef
+        .quad   0x2c7fba5d4442454e
+        .quad   0x5da87aa04795e441
+        .quad   0x413051e1a4e0b0f5
+        .quad   0x852dd1fd3d578bbe
+        .quad   0x2b65ce72c3286108
+        .quad   0x658c07f4eace2273
+        .quad   0x0933f804ec38ab40
+        .quad   0xa7ab69798d496476
+        .quad   0x8121aadefcb5abc8
+        .quad   0xa5dc12ef7b539472
+        .quad   0x07fd47065e45351a
+
+        // 2^180 * 2 * B
+
+        .quad   0xc8583c3d258d2bcd
+        .quad   0x17029a4daf60b73f
+        .quad   0xfa0fc9d6416a3781
+        .quad   0x1c1e5fba38b3fb23
+        .quad   0x304211559ae8e7c3
+        .quad   0xf281b229944882a5
+        .quad   0x8a13ac2e378250e4
+        .quad   0x014afa0954ba48f4
+        .quad   0xcb3197001bb3666c
+        .quad   0x330060524bffecb9
+        .quad   0x293711991a88233c
+        .quad   0x291884363d4ed364
+
+        // 2^180 * 3 * B
+
+        .quad   0x033c6805dc4babfa
+        .quad   0x2c15bf5e5596ecc1
+        .quad   0x1bc70624b59b1d3b
+        .quad   0x3ede9850a19f0ec5
+        .quad   0xfb9d37c3bc1ab6eb
+        .quad   0x02be14534d57a240
+        .quad   0xf4d73415f8a5e1f6
+        .quad   0x5964f4300ccc8188
+        .quad   0xe44a23152d096800
+        .quad   0x5c08c55970866996
+        .quad   0xdf2db60a46affb6e
+        .quad   0x579155c1f856fd89
+
+        // 2^180 * 4 * B
+
+        .quad   0x96324edd12e0c9ef
+        .quad   0x468b878df2420297
+        .quad   0x199a3776a4f573be
+        .quad   0x1e7fbcf18e91e92a
+        .quad   0xb5f16b630817e7a6
+        .quad   0x808c69233c351026
+        .quad   0x324a983b54cef201
+        .quad   0x53c092084a485345
+        .quad   0xd2d41481f1cbafbf
+        .quad   0x231d2db6716174e5
+        .quad   0x0b7d7656e2a55c98
+        .quad   0x3e955cd82aa495f6
+
+        // 2^180 * 5 * B
+
+        .quad   0xe48f535e3ed15433
+        .quad   0xd075692a0d7270a3
+        .quad   0x40fbd21daade6387
+        .quad   0x14264887cf4495f5
+        .quad   0xab39f3ef61bb3a3f
+        .quad   0x8eb400652eb9193e
+        .quad   0xb5de6ecc38c11f74
+        .quad   0x654d7e9626f3c49f
+        .quad   0xe564cfdd5c7d2ceb
+        .quad   0x82eeafded737ccb9
+        .quad   0x6107db62d1f9b0ab
+        .quad   0x0b6baac3b4358dbb
+
+        // 2^180 * 6 * B
+
+        .quad   0x7ae62bcb8622fe98
+        .quad   0x47762256ceb891af
+        .quad   0x1a5a92bcf2e406b4
+        .quad   0x7d29401784e41501
+        .quad   0x204abad63700a93b
+        .quad   0xbe0023d3da779373
+        .quad   0xd85f0346633ab709
+        .quad   0x00496dc490820412
+        .quad   0x1c74b88dc27e6360
+        .quad   0x074854268d14850c
+        .quad   0xa145fb7b3e0dcb30
+        .quad   0x10843f1b43803b23
+
+        // 2^180 * 7 * B
+
+        .quad   0xc5f90455376276dd
+        .quad   0xce59158dd7645cd9
+        .quad   0x92f65d511d366b39
+        .quad   0x11574b6e526996c4
+        .quad   0xd56f672de324689b
+        .quad   0xd1da8aedb394a981
+        .quad   0xdd7b58fe9168cfed
+        .quad   0x7ce246cd4d56c1e8
+        .quad   0xb8f4308e7f80be53
+        .quad   0x5f3cb8cb34a9d397
+        .quad   0x18a961bd33cc2b2c
+        .quad   0x710045fb3a9af671
+
+        // 2^180 * 8 * B
+
+        .quad   0x73f93d36101b95eb
+        .quad   0xfaef33794f6f4486
+        .quad   0x5651735f8f15e562
+        .quad   0x7fa3f19058b40da1
+        .quad   0xa03fc862059d699e
+        .quad   0x2370cfa19a619e69
+        .quad   0xc4fe3b122f823deb
+        .quad   0x1d1b056fa7f0844e
+        .quad   0x1bc64631e56bf61f
+        .quad   0xd379ab106e5382a3
+        .quad   0x4d58c57e0540168d
+        .quad   0x566256628442d8e4
+
+        // 2^184 * 1 * B
+
+        .quad   0xb9e499def6267ff6
+        .quad   0x7772ca7b742c0843
+        .quad   0x23a0153fe9a4f2b1
+        .quad   0x2cdfdfecd5d05006
+        .quad   0xdd499cd61ff38640
+        .quad   0x29cd9bc3063625a0
+        .quad   0x51e2d8023dd73dc3
+        .quad   0x4a25707a203b9231
+        .quad   0x2ab7668a53f6ed6a
+        .quad   0x304242581dd170a1
+        .quad   0x4000144c3ae20161
+        .quad   0x5721896d248e49fc
+
+        // 2^184 * 2 * B
+
+        .quad   0x0b6e5517fd181bae
+        .quad   0x9022629f2bb963b4
+        .quad   0x5509bce932064625
+        .quad   0x578edd74f63c13da
+        .quad   0x285d5091a1d0da4e
+        .quad   0x4baa6fa7b5fe3e08
+        .quad   0x63e5177ce19393b3
+        .quad   0x03c935afc4b030fd
+        .quad   0x997276c6492b0c3d
+        .quad   0x47ccc2c4dfe205fc
+        .quad   0xdcd29b84dd623a3c
+        .quad   0x3ec2ab590288c7a2
+
+        // 2^184 * 3 * B
+
+        .quad   0xa1a0d27be4d87bb9
+        .quad   0xa98b4deb61391aed
+        .quad   0x99a0ddd073cb9b83
+        .quad   0x2dd5c25a200fcace
+        .quad   0xa7213a09ae32d1cb
+        .quad   0x0f2b87df40f5c2d5
+        .quad   0x0baea4c6e81eab29
+        .quad   0x0e1bf66c6adbac5e
+        .quad   0xe2abd5e9792c887e
+        .quad   0x1a020018cb926d5d
+        .quad   0xbfba69cdbaae5f1e
+        .quad   0x730548b35ae88f5f
+
+        // 2^184 * 4 * B
+
+        .quad   0xc43551a3cba8b8ee
+        .quad   0x65a26f1db2115f16
+        .quad   0x760f4f52ab8c3850
+        .quad   0x3043443b411db8ca
+        .quad   0x805b094ba1d6e334
+        .quad   0xbf3ef17709353f19
+        .quad   0x423f06cb0622702b
+        .quad   0x585a2277d87845dd
+        .quad   0xa18a5f8233d48962
+        .quad   0x6698c4b5ec78257f
+        .quad   0xa78e6fa5373e41ff
+        .quad   0x7656278950ef981f
+
+        // 2^184 * 5 * B
+
+        .quad   0x38c3cf59d51fc8c0
+        .quad   0x9bedd2fd0506b6f2
+        .quad   0x26bf109fab570e8f
+        .quad   0x3f4160a8c1b846a6
+        .quad   0xe17073a3ea86cf9d
+        .quad   0x3a8cfbb707155fdc
+        .quad   0x4853e7fc31838a8e
+        .quad   0x28bbf484b613f616
+        .quad   0xf2612f5c6f136c7c
+        .quad   0xafead107f6dd11be
+        .quad   0x527e9ad213de6f33
+        .quad   0x1e79cb358188f75d
+
+        // 2^184 * 6 * B
+
+        .quad   0x013436c3eef7e3f1
+        .quad   0x828b6a7ffe9e10f8
+        .quad   0x7ff908e5bcf9defc
+        .quad   0x65d7951b3a3b3831
+        .quad   0x77e953d8f5e08181
+        .quad   0x84a50c44299dded9
+        .quad   0xdc6c2d0c864525e5
+        .quad   0x478ab52d39d1f2f4
+        .quad   0x66a6a4d39252d159
+        .quad   0xe5dde1bc871ac807
+        .quad   0xb82c6b40a6c1c96f
+        .quad   0x16d87a411a212214
+
+        // 2^184 * 7 * B
+
+        .quad   0xb3bd7e5a42066215
+        .quad   0x879be3cd0c5a24c1
+        .quad   0x57c05db1d6f994b7
+        .quad   0x28f87c8165f38ca6
+        .quad   0xfba4d5e2d54e0583
+        .quad   0xe21fafd72ebd99fa
+        .quad   0x497ac2736ee9778f
+        .quad   0x1f990b577a5a6dde
+        .quad   0xa3344ead1be8f7d6
+        .quad   0x7d1e50ebacea798f
+        .quad   0x77c6569e520de052
+        .quad   0x45882fe1534d6d3e
+
+        // 2^184 * 8 * B
+
+        .quad   0x6669345d757983d6
+        .quad   0x62b6ed1117aa11a6
+        .quad   0x7ddd1857985e128f
+        .quad   0x688fe5b8f626f6dd
+        .quad   0xd8ac9929943c6fe4
+        .quad   0xb5f9f161a38392a2
+        .quad   0x2699db13bec89af3
+        .quad   0x7dcf843ce405f074
+        .quad   0x6c90d6484a4732c0
+        .quad   0xd52143fdca563299
+        .quad   0xb3be28c3915dc6e1
+        .quad   0x6739687e7327191b
+
+        // 2^188 * 1 * B
+
+        .quad   0x9f65c5ea200814cf
+        .quad   0x840536e169a31740
+        .quad   0x8b0ed13925c8b4ad
+        .quad   0x0080dbafe936361d
+        .quad   0x8ce5aad0c9cb971f
+        .quad   0x1156aaa99fd54a29
+        .quad   0x41f7247015af9b78
+        .quad   0x1fe8cca8420f49aa
+        .quad   0x72a1848f3c0cc82a
+        .quad   0x38c560c2877c9e54
+        .quad   0x5004e228ce554140
+        .quad   0x042418a103429d71
+
+        // 2^188 * 2 * B
+
+        .quad   0x899dea51abf3ff5f
+        .quad   0x9b93a8672fc2d8ba
+        .quad   0x2c38cb97be6ebd5c
+        .quad   0x114d578497263b5d
+        .quad   0x58e84c6f20816247
+        .quad   0x8db2b2b6e36fd793
+        .quad   0x977182561d484d85
+        .quad   0x0822024f8632abd7
+        .quad   0xb301bb7c6b1beca3
+        .quad   0x55393f6dc6eb1375
+        .quad   0x910d281097b6e4eb
+        .quad   0x1ad4548d9d479ea3
+
+        // 2^188 * 3 * B
+
+        .quad   0xcd5a7da0389a48fd
+        .quad   0xb38fa4aa9a78371e
+        .quad   0xc6d9761b2cdb8e6c
+        .quad   0x35cf51dbc97e1443
+        .quad   0xa06fe66d0fe9fed3
+        .quad   0xa8733a401c587909
+        .quad   0x30d14d800df98953
+        .quad   0x41ce5876c7b30258
+        .quad   0x59ac3bc5d670c022
+        .quad   0xeae67c109b119406
+        .quad   0x9798bdf0b3782fda
+        .quad   0x651e3201fd074092
+
+        // 2^188 * 4 * B
+
+        .quad   0xd63d8483ef30c5cf
+        .quad   0x4cd4b4962361cc0c
+        .quad   0xee90e500a48426ac
+        .quad   0x0af51d7d18c14eeb
+        .quad   0xa57ba4a01efcae9e
+        .quad   0x769f4beedc308a94
+        .quad   0xd1f10eeb3603cb2e
+        .quad   0x4099ce5e7e441278
+        .quad   0x1ac98e4f8a5121e9
+        .quad   0x7dae9544dbfa2fe0
+        .quad   0x8320aa0dd6430df9
+        .quad   0x667282652c4a2fb5
+
+        // 2^188 * 5 * B
+
+        .quad   0x874621f4d86bc9ab
+        .quad   0xb54c7bbe56fe6fea
+        .quad   0x077a24257fadc22c
+        .quad   0x1ab53be419b90d39
+        .quad   0xada8b6e02946db23
+        .quad   0x1c0ce51a7b253ab7
+        .quad   0x8448c85a66dd485b
+        .quad   0x7f1fc025d0675adf
+        .quad   0xd8ee1b18319ea6aa
+        .quad   0x004d88083a21f0da
+        .quad   0x3bd6aa1d883a4f4b
+        .quad   0x4db9a3a6dfd9fd14
+
+        // 2^188 * 6 * B
+
+        .quad   0x8ce7b23bb99c0755
+        .quad   0x35c5d6edc4f50f7a
+        .quad   0x7e1e2ed2ed9b50c3
+        .quad   0x36305f16e8934da1
+        .quad   0xd95b00bbcbb77c68
+        .quad   0xddbc846a91f17849
+        .quad   0x7cf700aebe28d9b3
+        .quad   0x5ce1285c85d31f3e
+        .quad   0x31b6972d98b0bde8
+        .quad   0x7d920706aca6de5b
+        .quad   0xe67310f8908a659f
+        .quad   0x50fac2a6efdf0235
+
+        // 2^188 * 7 * B
+
+        .quad   0xf3d3a9f35b880f5a
+        .quad   0xedec050cdb03e7c2
+        .quad   0xa896981ff9f0b1a2
+        .quad   0x49a4ae2bac5e34a4
+        .quad   0x295b1c86f6f449bc
+        .quad   0x51b2e84a1f0ab4dd
+        .quad   0xc001cb30aa8e551d
+        .quad   0x6a28d35944f43662
+        .quad   0x28bb12ee04a740e0
+        .quad   0x14313bbd9bce8174
+        .quad   0x72f5b5e4e8c10c40
+        .quad   0x7cbfb19936adcd5b
+
+        // 2^188 * 8 * B
+
+        .quad   0xa311ddc26b89792d
+        .quad   0x1b30b4c6da512664
+        .quad   0x0ca77b4ccf150859
+        .quad   0x1de443df1b009408
+        .quad   0x8e793a7acc36e6e0
+        .quad   0xf9fab7a37d586eed
+        .quad   0x3a4f9692bae1f4e4
+        .quad   0x1c14b03eff5f447e
+        .quad   0x19647bd114a85291
+        .quad   0x57b76cb21034d3af
+        .quad   0x6329db440f9d6dfa
+        .quad   0x5ef43e586a571493
+
+        // 2^192 * 1 * B
+
+        .quad   0xef782014385675a6
+        .quad   0xa2649f30aafda9e8
+        .quad   0x4cd1eb505cdfa8cb
+        .quad   0x46115aba1d4dc0b3
+        .quad   0xa66dcc9dc80c1ac0
+        .quad   0x97a05cf41b38a436
+        .quad   0xa7ebf3be95dbd7c6
+        .quad   0x7da0b8f68d7e7dab
+        .quad   0xd40f1953c3b5da76
+        .quad   0x1dac6f7321119e9b
+        .quad   0x03cc6021feb25960
+        .quad   0x5a5f887e83674b4b
+
+        // 2^192 * 2 * B
+
+        .quad   0x8f6301cf70a13d11
+        .quad   0xcfceb815350dd0c4
+        .quad   0xf70297d4a4bca47e
+        .quad   0x3669b656e44d1434
+        .quad   0x9e9628d3a0a643b9
+        .quad   0xb5c3cb00e6c32064
+        .quad   0x9b5302897c2dec32
+        .quad   0x43e37ae2d5d1c70c
+        .quad   0x387e3f06eda6e133
+        .quad   0x67301d5199a13ac0
+        .quad   0xbd5ad8f836263811
+        .quad   0x6a21e6cd4fd5e9be
+
+        // 2^192 * 3 * B
+
+        .quad   0xf1c6170a3046e65f
+        .quad   0x58712a2a00d23524
+        .quad   0x69dbbd3c8c82b755
+        .quad   0x586bf9f1a195ff57
+        .quad   0xef4129126699b2e3
+        .quad   0x71d30847708d1301
+        .quad   0x325432d01182b0bd
+        .quad   0x45371b07001e8b36
+        .quad   0xa6db088d5ef8790b
+        .quad   0x5278f0dc610937e5
+        .quad   0xac0349d261a16eb8
+        .quad   0x0eafb03790e52179
+
+        // 2^192 * 4 * B
+
+        .quad   0x960555c13748042f
+        .quad   0x219a41e6820baa11
+        .quad   0x1c81f73873486d0c
+        .quad   0x309acc675a02c661
+        .quad   0x5140805e0f75ae1d
+        .quad   0xec02fbe32662cc30
+        .quad   0x2cebdf1eea92396d
+        .quad   0x44ae3344c5435bb3
+        .quad   0x9cf289b9bba543ee
+        .quad   0xf3760e9d5ac97142
+        .quad   0x1d82e5c64f9360aa
+        .quad   0x62d5221b7f94678f
+
+        // 2^192 * 5 * B
+
+        .quad   0x524c299c18d0936d
+        .quad   0xc86bb56c8a0c1a0c
+        .quad   0xa375052edb4a8631
+        .quad   0x5c0efde4bc754562
+        .quad   0x7585d4263af77a3c
+        .quad   0xdfae7b11fee9144d
+        .quad   0xa506708059f7193d
+        .quad   0x14f29a5383922037
+        .quad   0xdf717edc25b2d7f5
+        .quad   0x21f970db99b53040
+        .quad   0xda9234b7c3ed4c62
+        .quad   0x5e72365c7bee093e
+
+        // 2^192 * 6 * B
+
+        .quad   0x575bfc074571217f
+        .quad   0x3779675d0694d95b
+        .quad   0x9a0a37bbf4191e33
+        .quad   0x77f1104c47b4eabc
+        .quad   0x7d9339062f08b33e
+        .quad   0x5b9659e5df9f32be
+        .quad   0xacff3dad1f9ebdfd
+        .quad   0x70b20555cb7349b7
+        .quad   0xbe5113c555112c4c
+        .quad   0x6688423a9a881fcd
+        .quad   0x446677855e503b47
+        .quad   0x0e34398f4a06404a
+
+        // 2^192 * 7 * B
+
+        .quad   0xb67d22d93ecebde8
+        .quad   0x09b3e84127822f07
+        .quad   0x743fa61fb05b6d8d
+        .quad   0x5e5405368a362372
+        .quad   0x18930b093e4b1928
+        .quad   0x7de3e10e73f3f640
+        .quad   0xf43217da73395d6f
+        .quad   0x6f8aded6ca379c3e
+        .quad   0xe340123dfdb7b29a
+        .quad   0x487b97e1a21ab291
+        .quad   0xf9967d02fde6949e
+        .quad   0x780de72ec8d3de97
+
+        // 2^192 * 8 * B
+
+        .quad   0x0ae28545089ae7bc
+        .quad   0x388ddecf1c7f4d06
+        .quad   0x38ac15510a4811b8
+        .quad   0x0eb28bf671928ce4
+        .quad   0x671feaf300f42772
+        .quad   0x8f72eb2a2a8c41aa
+        .quad   0x29a17fd797373292
+        .quad   0x1defc6ad32b587a6
+        .quad   0xaf5bbe1aef5195a7
+        .quad   0x148c1277917b15ed
+        .quad   0x2991f7fb7ae5da2e
+        .quad   0x467d201bf8dd2867
+
+        // 2^196 * 1 * B
+
+        .quad   0x7906ee72f7bd2e6b
+        .quad   0x05d270d6109abf4e
+        .quad   0x8d5cfe45b941a8a4
+        .quad   0x44c218671c974287
+        .quad   0x745f9d56296bc318
+        .quad   0x993580d4d8152e65
+        .quad   0xb0e5b13f5839e9ce
+        .quad   0x51fc2b28d43921c0
+        .quad   0x1b8fd11795e2a98c
+        .quad   0x1c4e5ee12b6b6291
+        .quad   0x5b30e7107424b572
+        .quad   0x6e6b9de84c4f4ac6
+
+        // 2^196 * 2 * B
+
+        .quad   0xdff25fce4b1de151
+        .quad   0xd841c0c7e11c4025
+        .quad   0x2554b3c854749c87
+        .quad   0x2d292459908e0df9
+        .quad   0x6b7c5f10f80cb088
+        .quad   0x736b54dc56e42151
+        .quad   0xc2b620a5c6ef99c4
+        .quad   0x5f4c802cc3a06f42
+        .quad   0x9b65c8f17d0752da
+        .quad   0x881ce338c77ee800
+        .quad   0xc3b514f05b62f9e3
+        .quad   0x66ed5dd5bec10d48
+
+        // 2^196 * 3 * B
+
+        .quad   0x7d38a1c20bb2089d
+        .quad   0x808334e196ccd412
+        .quad   0xc4a70b8c6c97d313
+        .quad   0x2eacf8bc03007f20
+        .quad   0xf0adf3c9cbca047d
+        .quad   0x81c3b2cbf4552f6b
+        .quad   0xcfda112d44735f93
+        .quad   0x1f23a0c77e20048c
+        .quad   0xf235467be5bc1570
+        .quad   0x03d2d9020dbab38c
+        .quad   0x27529aa2fcf9e09e
+        .quad   0x0840bef29d34bc50
+
+        // 2^196 * 4 * B
+
+        .quad   0x796dfb35dc10b287
+        .quad   0x27176bcd5c7ff29d
+        .quad   0x7f3d43e8c7b24905
+        .quad   0x0304f5a191c54276
+        .quad   0xcd54e06b7f37e4eb
+        .quad   0x8cc15f87f5e96cca
+        .quad   0xb8248bb0d3597dce
+        .quad   0x246affa06074400c
+        .quad   0x37d88e68fbe45321
+        .quad   0x86097548c0d75032
+        .quad   0x4e9b13ef894a0d35
+        .quad   0x25a83cac5753d325
+
+        // 2^196 * 5 * B
+
+        .quad   0x10222f48eed8165e
+        .quad   0x623fc1234b8bcf3a
+        .quad   0x1e145c09c221e8f0
+        .quad   0x7ccfa59fca782630
+        .quad   0x9f0f66293952b6e2
+        .quad   0x33db5e0e0934267b
+        .quad   0xff45252bd609fedc
+        .quad   0x06be10f5c506e0c9
+        .quad   0x1a9615a9b62a345f
+        .quad   0x22050c564a52fecc
+        .quad   0xa7a2788528bc0dfe
+        .quad   0x5e82770a1a1ee71d
+
+        // 2^196 * 6 * B
+
+        .quad   0x35425183ad896a5c
+        .quad   0xe8673afbe78d52f6
+        .quad   0x2c66f25f92a35f64
+        .quad   0x09d04f3b3b86b102
+        .quad   0xe802e80a42339c74
+        .quad   0x34175166a7fffae5
+        .quad   0x34865d1f1c408cae
+        .quad   0x2cca982c605bc5ee
+        .quad   0xfd2d5d35197dbe6e
+        .quad   0x207c2eea8be4ffa3
+        .quad   0x2613d8db325ae918
+        .quad   0x7a325d1727741d3e
+
+        // 2^196 * 7 * B
+
+        .quad   0xd036b9bbd16dfde2
+        .quad   0xa2055757c497a829
+        .quad   0x8e6cc966a7f12667
+        .quad   0x4d3b1a791239c180
+        .quad   0xecd27d017e2a076a
+        .quad   0xd788689f1636495e
+        .quad   0x52a61af0919233e5
+        .quad   0x2a479df17bb1ae64
+        .quad   0x9e5eee8e33db2710
+        .quad   0x189854ded6c43ca5
+        .quad   0xa41c22c592718138
+        .quad   0x27ad5538a43a5e9b
+
+        // 2^196 * 8 * B
+
+        .quad   0x2746dd4b15350d61
+        .quad   0xd03fcbc8ee9521b7
+        .quad   0xe86e365a138672ca
+        .quad   0x510e987f7e7d89e2
+        .quad   0xcb5a7d638e47077c
+        .quad   0x8db7536120a1c059
+        .quad   0x549e1e4d8bedfdcc
+        .quad   0x080153b7503b179d
+        .quad   0xdda69d930a3ed3e3
+        .quad   0x3d386ef1cd60a722
+        .quad   0xc817ad58bdaa4ee6
+        .quad   0x23be8d554fe7372a
+
+        // 2^200 * 1 * B
+
+        .quad   0x95fe919a74ef4fad
+        .quad   0x3a827becf6a308a2
+        .quad   0x964e01d309a47b01
+        .quad   0x71c43c4f5ba3c797
+        .quad   0xbc1ef4bd567ae7a9
+        .quad   0x3f624cb2d64498bd
+        .quad   0xe41064d22c1f4ec8
+        .quad   0x2ef9c5a5ba384001
+        .quad   0xb6fd6df6fa9e74cd
+        .quad   0xf18278bce4af267a
+        .quad   0x8255b3d0f1ef990e
+        .quad   0x5a758ca390c5f293
+
+        // 2^200 * 2 * B
+
+        .quad   0xa2b72710d9462495
+        .quad   0x3aa8c6d2d57d5003
+        .quad   0xe3d400bfa0b487ca
+        .quad   0x2dbae244b3eb72ec
+        .quad   0x8ce0918b1d61dc94
+        .quad   0x8ded36469a813066
+        .quad   0xd4e6a829afe8aad3
+        .quad   0x0a738027f639d43f
+        .quad   0x980f4a2f57ffe1cc
+        .quad   0x00670d0de1839843
+        .quad   0x105c3f4a49fb15fd
+        .quad   0x2698ca635126a69c
+
+        // 2^200 * 3 * B
+
+        .quad   0xe765318832b0ba78
+        .quad   0x381831f7925cff8b
+        .quad   0x08a81b91a0291fcc
+        .quad   0x1fb43dcc49caeb07
+        .quad   0x2e3d702f5e3dd90e
+        .quad   0x9e3f0918e4d25386
+        .quad   0x5e773ef6024da96a
+        .quad   0x3c004b0c4afa3332
+        .quad   0x9aa946ac06f4b82b
+        .quad   0x1ca284a5a806c4f3
+        .quad   0x3ed3265fc6cd4787
+        .quad   0x6b43fd01cd1fd217
+
+        // 2^200 * 4 * B
+
+        .quad   0xc7a75d4b4697c544
+        .quad   0x15fdf848df0fffbf
+        .quad   0x2868b9ebaa46785a
+        .quad   0x5a68d7105b52f714
+        .quad   0xb5c742583e760ef3
+        .quad   0x75dc52b9ee0ab990
+        .quad   0xbf1427c2072b923f
+        .quad   0x73420b2d6ff0d9f0
+        .quad   0xaf2cf6cb9e851e06
+        .quad   0x8f593913c62238c4
+        .quad   0xda8ab89699fbf373
+        .quad   0x3db5632fea34bc9e
+
+        // 2^200 * 5 * B
+
+        .quad   0xf46eee2bf75dd9d8
+        .quad   0x0d17b1f6396759a5
+        .quad   0x1bf2d131499e7273
+        .quad   0x04321adf49d75f13
+        .quad   0x2e4990b1829825d5
+        .quad   0xedeaeb873e9a8991
+        .quad   0xeef03d394c704af8
+        .quad   0x59197ea495df2b0e
+        .quad   0x04e16019e4e55aae
+        .quad   0xe77b437a7e2f92e9
+        .quad   0xc7ce2dc16f159aa4
+        .quad   0x45eafdc1f4d70cc0
+
+        // 2^200 * 6 * B
+
+        .quad   0x698401858045d72b
+        .quad   0x4c22faa2cf2f0651
+        .quad   0x941a36656b222dc6
+        .quad   0x5a5eebc80362dade
+        .quad   0xb60e4624cfccb1ed
+        .quad   0x59dbc292bd5c0395
+        .quad   0x31a09d1ddc0481c9
+        .quad   0x3f73ceea5d56d940
+        .quad   0xb7a7bfd10a4e8dc6
+        .quad   0xbe57007e44c9b339
+        .quad   0x60c1207f1557aefa
+        .quad   0x26058891266218db
+
+        // 2^200 * 7 * B
+
+        .quad   0x59f704a68360ff04
+        .quad   0xc3d93fde7661e6f4
+        .quad   0x831b2a7312873551
+        .quad   0x54ad0c2e4e615d57
+        .quad   0x4c818e3cc676e542
+        .quad   0x5e422c9303ceccad
+        .quad   0xec07cccab4129f08
+        .quad   0x0dedfa10b24443b8
+        .quad   0xee3b67d5b82b522a
+        .quad   0x36f163469fa5c1eb
+        .quad   0xa5b4d2f26ec19fd3
+        .quad   0x62ecb2baa77a9408
+
+        // 2^200 * 8 * B
+
+        .quad   0xe5ed795261152b3d
+        .quad   0x4962357d0eddd7d1
+        .quad   0x7482c8d0b96b4c71
+        .quad   0x2e59f919a966d8be
+        .quad   0x92072836afb62874
+        .quad   0x5fcd5e8579e104a5
+        .quad   0x5aad01adc630a14a
+        .quad   0x61913d5075663f98
+        .quad   0x0dc62d361a3231da
+        .quad   0xfa47583294200270
+        .quad   0x02d801513f9594ce
+        .quad   0x3ddbc2a131c05d5c
+
+        // 2^204 * 1 * B
+
+        .quad   0x3f50a50a4ffb81ef
+        .quad   0xb1e035093bf420bf
+        .quad   0x9baa8e1cc6aa2cd0
+        .quad   0x32239861fa237a40
+        .quad   0xfb735ac2004a35d1
+        .quad   0x31de0f433a6607c3
+        .quad   0x7b8591bfc528d599
+        .quad   0x55be9a25f5bb050c
+        .quad   0x0d005acd33db3dbf
+        .quad   0x0111b37c80ac35e2
+        .quad   0x4892d66c6f88ebeb
+        .quad   0x770eadb16508fbcd
+
+        // 2^204 * 2 * B
+
+        .quad   0x8451f9e05e4e89dd
+        .quad   0xc06302ffbc793937
+        .quad   0x5d22749556a6495c
+        .quad   0x09a6755ca05603fb
+        .quad   0xf1d3b681a05071b9
+        .quad   0x2207659a3592ff3a
+        .quad   0x5f0169297881e40e
+        .quad   0x16bedd0e86ba374e
+        .quad   0x5ecccc4f2c2737b5
+        .quad   0x43b79e0c2dccb703
+        .quad   0x33e008bc4ec43df3
+        .quad   0x06c1b840f07566c0
+
+        // 2^204 * 3 * B
+
+        .quad   0x7688a5c6a388f877
+        .quad   0x02a96c14deb2b6ac
+        .quad   0x64c9f3431b8c2af8
+        .quad   0x3628435554a1eed6
+        .quad   0x69ee9e7f9b02805c
+        .quad   0xcbff828a547d1640
+        .quad   0x3d93a869b2430968
+        .quad   0x46b7b8cd3fe26972
+        .quad   0xe9812086fe7eebe0
+        .quad   0x4cba6be72f515437
+        .quad   0x1d04168b516efae9
+        .quad   0x5ea1391043982cb9
+
+        // 2^204 * 4 * B
+
+        .quad   0x49125c9cf4702ee1
+        .quad   0x4520b71f8b25b32d
+        .quad   0x33193026501fef7e
+        .quad   0x656d8997c8d2eb2b
+        .quad   0x6f2b3be4d5d3b002
+        .quad   0xafec33d96a09c880
+        .quad   0x035f73a4a8bcc4cc
+        .quad   0x22c5b9284662198b
+        .quad   0xcb58c8fe433d8939
+        .quad   0x89a0cb2e6a8d7e50
+        .quad   0x79ca955309fbbe5a
+        .quad   0x0c626616cd7fc106
+
+        // 2^204 * 5 * B
+
+        .quad   0x1ffeb80a4879b61f
+        .quad   0x6396726e4ada21ed
+        .quad   0x33c7b093368025ba
+        .quad   0x471aa0c6f3c31788
+        .quad   0x8fdfc379fbf454b1
+        .quad   0x45a5a970f1a4b771
+        .quad   0xac921ef7bad35915
+        .quad   0x42d088dca81c2192
+        .quad   0x8fda0f37a0165199
+        .quad   0x0adadb77c8a0e343
+        .quad   0x20fbfdfcc875e820
+        .quad   0x1cf2bea80c2206e7
+
+        // 2^204 * 6 * B
+
+        .quad   0xc2ddf1deb36202ac
+        .quad   0x92a5fe09d2e27aa5
+        .quad   0x7d1648f6fc09f1d3
+        .quad   0x74c2cc0513bc4959
+        .quad   0x982d6e1a02c0412f
+        .quad   0x90fa4c83db58e8fe
+        .quad   0x01c2f5bcdcb18bc0
+        .quad   0x686e0c90216abc66
+        .quad   0x1fadbadba54395a7
+        .quad   0xb41a02a0ae0da66a
+        .quad   0xbf19f598bba37c07
+        .quad   0x6a12b8acde48430d
+
+        // 2^204 * 7 * B
+
+        .quad   0xf8daea1f39d495d9
+        .quad   0x592c190e525f1dfc
+        .quad   0xdb8cbd04c9991d1b
+        .quad   0x11f7fda3d88f0cb7
+        .quad   0x793bdd801aaeeb5f
+        .quad   0x00a2a0aac1518871
+        .quad   0xe8a373a31f2136b4
+        .quad   0x48aab888fc91ef19
+        .quad   0x041f7e925830f40e
+        .quad   0x002d6ca979661c06
+        .quad   0x86dc9ff92b046a2e
+        .quad   0x760360928b0493d1
+
+        // 2^204 * 8 * B
+
+        .quad   0x21bb41c6120cf9c6
+        .quad   0xeab2aa12decda59b
+        .quad   0xc1a72d020aa48b34
+        .quad   0x215d4d27e87d3b68
+        .quad   0xb43108e5695a0b05
+        .quad   0x6cb00ee8ad37a38b
+        .quad   0x5edad6eea3537381
+        .quad   0x3f2602d4b6dc3224
+        .quad   0xc8b247b65bcaf19c
+        .quad   0x49779dc3b1b2c652
+        .quad   0x89a180bbd5ece2e2
+        .quad   0x13f098a3cec8e039
+
+        // 2^208 * 1 * B
+
+        .quad   0x9adc0ff9ce5ec54b
+        .quad   0x039c2a6b8c2f130d
+        .quad   0x028007c7f0f89515
+        .quad   0x78968314ac04b36b
+        .quad   0xf3aa57a22796bb14
+        .quad   0x883abab79b07da21
+        .quad   0xe54be21831a0391c
+        .quad   0x5ee7fb38d83205f9
+        .quad   0x538dfdcb41446a8e
+        .quad   0xa5acfda9434937f9
+        .quad   0x46af908d263c8c78
+        .quad   0x61d0633c9bca0d09
+
+        // 2^208 * 2 * B
+
+        .quad   0x63744935ffdb2566
+        .quad   0xc5bd6b89780b68bb
+        .quad   0x6f1b3280553eec03
+        .quad   0x6e965fd847aed7f5
+        .quad   0xada328bcf8fc73df
+        .quad   0xee84695da6f037fc
+        .quad   0x637fb4db38c2a909
+        .quad   0x5b23ac2df8067bdc
+        .quad   0x9ad2b953ee80527b
+        .quad   0xe88f19aafade6d8d
+        .quad   0x0e711704150e82cf
+        .quad   0x79b9bbb9dd95dedc
+
+        // 2^208 * 3 * B
+
+        .quad   0xebb355406a3126c2
+        .quad   0xd26383a868c8c393
+        .quad   0x6c0c6429e5b97a82
+        .quad   0x5065f158c9fd2147
+        .quad   0xd1997dae8e9f7374
+        .quad   0xa032a2f8cfbb0816
+        .quad   0xcd6cba126d445f0a
+        .quad   0x1ba811460accb834
+        .quad   0x708169fb0c429954
+        .quad   0xe14600acd76ecf67
+        .quad   0x2eaab98a70e645ba
+        .quad   0x3981f39e58a4faf2
+
+        // 2^208 * 4 * B
+
+        .quad   0x18fb8a7559230a93
+        .quad   0x1d168f6960e6f45d
+        .quad   0x3a85a94514a93cb5
+        .quad   0x38dc083705acd0fd
+        .quad   0xc845dfa56de66fde
+        .quad   0xe152a5002c40483a
+        .quad   0xe9d2e163c7b4f632
+        .quad   0x30f4452edcbc1b65
+        .quad   0x856d2782c5759740
+        .quad   0xfa134569f99cbecc
+        .quad   0x8844fc73c0ea4e71
+        .quad   0x632d9a1a593f2469
+
+        // 2^208 * 5 * B
+
+        .quad   0xf6bb6b15b807cba6
+        .quad   0x1823c7dfbc54f0d7
+        .quad   0xbb1d97036e29670b
+        .quad   0x0b24f48847ed4a57
+        .quad   0xbf09fd11ed0c84a7
+        .quad   0x63f071810d9f693a
+        .quad   0x21908c2d57cf8779
+        .quad   0x3a5a7df28af64ba2
+        .quad   0xdcdad4be511beac7
+        .quad   0xa4538075ed26ccf2
+        .quad   0xe19cff9f005f9a65
+        .quad   0x34fcf74475481f63
+
+        // 2^208 * 6 * B
+
+        .quad   0xc197e04c789767ca
+        .quad   0xb8714dcb38d9467d
+        .quad   0x55de888283f95fa8
+        .quad   0x3d3bdc164dfa63f7
+        .quad   0xa5bb1dab78cfaa98
+        .quad   0x5ceda267190b72f2
+        .quad   0x9309c9110a92608e
+        .quad   0x0119a3042fb374b0
+        .quad   0x67a2d89ce8c2177d
+        .quad   0x669da5f66895d0c1
+        .quad   0xf56598e5b282a2b0
+        .quad   0x56c088f1ede20a73
+
+        // 2^208 * 7 * B
+
+        .quad   0x336d3d1110a86e17
+        .quad   0xd7f388320b75b2fa
+        .quad   0xf915337625072988
+        .quad   0x09674c6b99108b87
+        .quad   0x581b5fac24f38f02
+        .quad   0xa90be9febae30cbd
+        .quad   0x9a2169028acf92f0
+        .quad   0x038b7ea48359038f
+        .quad   0x9f4ef82199316ff8
+        .quad   0x2f49d282eaa78d4f
+        .quad   0x0971a5ab5aef3174
+        .quad   0x6e5e31025969eb65
+
+        // 2^208 * 8 * B
+
+        .quad   0xb16c62f587e593fb
+        .quad   0x4999eddeca5d3e71
+        .quad   0xb491c1e014cc3e6d
+        .quad   0x08f5114789a8dba8
+        .quad   0x3304fb0e63066222
+        .quad   0xfb35068987acba3f
+        .quad   0xbd1924778c1061a3
+        .quad   0x3058ad43d1838620
+        .quad   0x323c0ffde57663d0
+        .quad   0x05c3df38a22ea610
+        .quad   0xbdc78abdac994f9a
+        .quad   0x26549fa4efe3dc99
+
+        // 2^212 * 1 * B
+
+        .quad   0x738b38d787ce8f89
+        .quad   0xb62658e24179a88d
+        .quad   0x30738c9cf151316d
+        .quad   0x49128c7f727275c9
+        .quad   0x04dbbc17f75396b9
+        .quad   0x69e6a2d7d2f86746
+        .quad   0xc6409d99f53eabc6
+        .quad   0x606175f6332e25d2
+        .quad   0x4021370ef540e7dd
+        .quad   0x0910d6f5a1f1d0a5
+        .quad   0x4634aacd5b06b807
+        .quad   0x6a39e6356944f235
+
+        // 2^212 * 2 * B
+
+        .quad   0x96cd5640df90f3e7
+        .quad   0x6c3a760edbfa25ea
+        .quad   0x24f3ef0959e33cc4
+        .quad   0x42889e7e530d2e58
+        .quad   0x1da1965774049e9d
+        .quad   0xfbcd6ea198fe352b
+        .quad   0xb1cbcd50cc5236a6
+        .quad   0x1f5ec83d3f9846e2
+        .quad   0x8efb23c3328ccb75
+        .quad   0xaf42a207dd876ee9
+        .quad   0x20fbdadc5dfae796
+        .quad   0x241e246b06bf9f51
+
+        // 2^212 * 3 * B
+
+        .quad   0x29e68e57ad6e98f6
+        .quad   0x4c9260c80b462065
+        .quad   0x3f00862ea51ebb4b
+        .quad   0x5bc2c77fb38d9097
+        .quad   0x7eaafc9a6280bbb8
+        .quad   0x22a70f12f403d809
+        .quad   0x31ce40bb1bfc8d20
+        .quad   0x2bc65635e8bd53ee
+        .quad   0xe8d5dc9fa96bad93
+        .quad   0xe58fb17dde1947dc
+        .quad   0x681532ea65185fa3
+        .quad   0x1fdd6c3b034a7830
+
+        // 2^212 * 4 * B
+
+        .quad   0x0a64e28c55dc18fe
+        .quad   0xe3df9e993399ebdd
+        .quad   0x79ac432370e2e652
+        .quad   0x35ff7fc33ae4cc0e
+        .quad   0x9c13a6a52dd8f7a9
+        .quad   0x2dbb1f8c3efdcabf
+        .quad   0x961e32405e08f7b5
+        .quad   0x48c8a121bbe6c9e5
+        .quad   0xfc415a7c59646445
+        .quad   0xd224b2d7c128b615
+        .quad   0x6035c9c905fbb912
+        .quad   0x42d7a91274429fab
+
+        // 2^212 * 5 * B
+
+        .quad   0x4e6213e3eaf72ed3
+        .quad   0x6794981a43acd4e7
+        .quad   0xff547cde6eb508cb
+        .quad   0x6fed19dd10fcb532
+        .quad   0xa9a48947933da5bc
+        .quad   0x4a58920ec2e979ec
+        .quad   0x96d8800013e5ac4c
+        .quad   0x453692d74b48b147
+        .quad   0xdd775d99a8559c6f
+        .quad   0xf42a2140df003e24
+        .quad   0x5223e229da928a66
+        .quad   0x063f46ba6d38f22c
+
+        // 2^212 * 6 * B
+
+        .quad   0xd2d242895f536694
+        .quad   0xca33a2c542939b2c
+        .quad   0x986fada6c7ddb95c
+        .quad   0x5a152c042f712d5d
+        .quad   0x39843cb737346921
+        .quad   0xa747fb0738c89447
+        .quad   0xcb8d8031a245307e
+        .quad   0x67810f8e6d82f068
+        .quad   0x3eeb8fbcd2287db4
+        .quad   0x72c7d3a301a03e93
+        .quad   0x5473e88cbd98265a
+        .quad   0x7324aa515921b403
+
+        // 2^212 * 7 * B
+
+        .quad   0x857942f46c3cbe8e
+        .quad   0xa1d364b14730c046
+        .quad   0x1c8ed914d23c41bf
+        .quad   0x0838e161eef6d5d2
+        .quad   0xad23f6dae82354cb
+        .quad   0x6962502ab6571a6d
+        .quad   0x9b651636e38e37d1
+        .quad   0x5cac5005d1a3312f
+        .quad   0x8cc154cce9e39904
+        .quad   0x5b3a040b84de6846
+        .quad   0xc4d8a61cb1be5d6e
+        .quad   0x40fb897bd8861f02
+
+        // 2^212 * 8 * B
+
+        .quad   0x84c5aa9062de37a1
+        .quad   0x421da5000d1d96e1
+        .quad   0x788286306a9242d9
+        .quad   0x3c5e464a690d10da
+        .quad   0xe57ed8475ab10761
+        .quad   0x71435e206fd13746
+        .quad   0x342f824ecd025632
+        .quad   0x4b16281ea8791e7b
+        .quad   0xd1c101d50b813381
+        .quad   0xdee60f1176ee6828
+        .quad   0x0cb68893383f6409
+        .quad   0x6183c565f6ff484a
+
+        // 2^216 * 1 * B
+
+        .quad   0x741d5a461e6bf9d6
+        .quad   0x2305b3fc7777a581
+        .quad   0xd45574a26474d3d9
+        .quad   0x1926e1dc6401e0ff
+        .quad   0xdb468549af3f666e
+        .quad   0xd77fcf04f14a0ea5
+        .quad   0x3df23ff7a4ba0c47
+        .quad   0x3a10dfe132ce3c85
+        .quad   0xe07f4e8aea17cea0
+        .quad   0x2fd515463a1fc1fd
+        .quad   0x175322fd31f2c0f1
+        .quad   0x1fa1d01d861e5d15
+
+        // 2^216 * 2 * B
+
+        .quad   0xcc8055947d599832
+        .quad   0x1e4656da37f15520
+        .quad   0x99f6f7744e059320
+        .quad   0x773563bc6a75cf33
+        .quad   0x38dcac00d1df94ab
+        .quad   0x2e712bddd1080de9
+        .quad   0x7f13e93efdd5e262
+        .quad   0x73fced18ee9a01e5
+        .quad   0x06b1e90863139cb3
+        .quad   0xa493da67c5a03ecd
+        .quad   0x8d77cec8ad638932
+        .quad   0x1f426b701b864f44
+
+        // 2^216 * 3 * B
+
+        .quad   0xefc9264c41911c01
+        .quad   0xf1a3b7b817a22c25
+        .quad   0x5875da6bf30f1447
+        .quad   0x4e1af5271d31b090
+        .quad   0xf17e35c891a12552
+        .quad   0xb76b8153575e9c76
+        .quad   0xfa83406f0d9b723e
+        .quad   0x0b76bb1b3fa7e438
+        .quad   0x08b8c1f97f92939b
+        .quad   0xbe6771cbd444ab6e
+        .quad   0x22e5646399bb8017
+        .quad   0x7b6dd61eb772a955
+
+        // 2^216 * 4 * B
+
+        .quad   0xb7adc1e850f33d92
+        .quad   0x7998fa4f608cd5cf
+        .quad   0xad962dbd8dfc5bdb
+        .quad   0x703e9bceaf1d2f4f
+        .quad   0x5730abf9ab01d2c7
+        .quad   0x16fb76dc40143b18
+        .quad   0x866cbe65a0cbb281
+        .quad   0x53fa9b659bff6afe
+        .quad   0x6c14c8e994885455
+        .quad   0x843a5d6665aed4e5
+        .quad   0x181bb73ebcd65af1
+        .quad   0x398d93e5c4c61f50
+
+        // 2^216 * 5 * B
+
+        .quad   0x1c4bd16733e248f3
+        .quad   0xbd9e128715bf0a5f
+        .quad   0xd43f8cf0a10b0376
+        .quad   0x53b09b5ddf191b13
+        .quad   0xc3877c60d2e7e3f2
+        .quad   0x3b34aaa030828bb1
+        .quad   0x283e26e7739ef138
+        .quad   0x699c9c9002c30577
+        .quad   0xf306a7235946f1cc
+        .quad   0x921718b5cce5d97d
+        .quad   0x28cdd24781b4e975
+        .quad   0x51caf30c6fcdd907
+
+        // 2^216 * 6 * B
+
+        .quad   0xa60ba7427674e00a
+        .quad   0x630e8570a17a7bf3
+        .quad   0x3758563dcf3324cc
+        .quad   0x5504aa292383fdaa
+        .quad   0x737af99a18ac54c7
+        .quad   0x903378dcc51cb30f
+        .quad   0x2b89bc334ce10cc7
+        .quad   0x12ae29c189f8e99a
+        .quad   0xa99ec0cb1f0d01cf
+        .quad   0x0dd1efcc3a34f7ae
+        .quad   0x55ca7521d09c4e22
+        .quad   0x5fd14fe958eba5ea
+
+        // 2^216 * 7 * B
+
+        .quad   0xb5dc2ddf2845ab2c
+        .quad   0x069491b10a7fe993
+        .quad   0x4daaf3d64002e346
+        .quad   0x093ff26e586474d1
+        .quad   0x3c42fe5ebf93cb8e
+        .quad   0xbedfa85136d4565f
+        .quad   0xe0f0859e884220e8
+        .quad   0x7dd73f960725d128
+        .quad   0xb10d24fe68059829
+        .quad   0x75730672dbaf23e5
+        .quad   0x1367253ab457ac29
+        .quad   0x2f59bcbc86b470a4
+
+        // 2^216 * 8 * B
+
+        .quad   0x83847d429917135f
+        .quad   0xad1b911f567d03d7
+        .quad   0x7e7748d9be77aad1
+        .quad   0x5458b42e2e51af4a
+        .quad   0x7041d560b691c301
+        .quad   0x85201b3fadd7e71e
+        .quad   0x16c2e16311335585
+        .quad   0x2aa55e3d010828b1
+        .quad   0xed5192e60c07444f
+        .quad   0x42c54e2d74421d10
+        .quad   0x352b4c82fdb5c864
+        .quad   0x13e9004a8a768664
+
+        // 2^220 * 1 * B
+
+        .quad   0xcbb5b5556c032bff
+        .quad   0xdf7191b729297a3a
+        .quad   0xc1ff7326aded81bb
+        .quad   0x71ade8bb68be03f5
+        .quad   0x1e6284c5806b467c
+        .quad   0xc5f6997be75d607b
+        .quad   0x8b67d958b378d262
+        .quad   0x3d88d66a81cd8b70
+        .quad   0x8b767a93204ed789
+        .quad   0x762fcacb9fa0ae2a
+        .quad   0x771febcc6dce4887
+        .quad   0x343062158ff05fb3
+
+        // 2^220 * 2 * B
+
+        .quad   0xe05da1a7e1f5bf49
+        .quad   0x26457d6dd4736092
+        .quad   0x77dcb07773cc32f6
+        .quad   0x0a5d94969cdd5fcd
+        .quad   0xfce219072a7b31b4
+        .quad   0x4d7adc75aa578016
+        .quad   0x0ec276a687479324
+        .quad   0x6d6d9d5d1fda4beb
+        .quad   0x22b1a58ae9b08183
+        .quad   0xfd95d071c15c388b
+        .quad   0xa9812376850a0517
+        .quad   0x33384cbabb7f335e
+
+        // 2^220 * 3 * B
+
+        .quad   0x3c6fa2680ca2c7b5
+        .quad   0x1b5082046fb64fda
+        .quad   0xeb53349c5431d6de
+        .quad   0x5278b38f6b879c89
+        .quad   0x33bc627a26218b8d
+        .quad   0xea80b21fc7a80c61
+        .quad   0x9458b12b173e9ee6
+        .quad   0x076247be0e2f3059
+        .quad   0x52e105f61416375a
+        .quad   0xec97af3685abeba4
+        .quad   0x26e6b50623a67c36
+        .quad   0x5cf0e856f3d4fb01
+
+        // 2^220 * 4 * B
+
+        .quad   0xf6c968731ae8cab4
+        .quad   0x5e20741ecb4f92c5
+        .quad   0x2da53be58ccdbc3e
+        .quad   0x2dddfea269970df7
+        .quad   0xbeaece313db342a8
+        .quad   0xcba3635b842db7ee
+        .quad   0xe88c6620817f13ef
+        .quad   0x1b9438aa4e76d5c6
+        .quad   0x8a50777e166f031a
+        .quad   0x067b39f10fb7a328
+        .quad   0x1925c9a6010fbd76
+        .quad   0x6df9b575cc740905
+
+        // 2^220 * 5 * B
+
+        .quad   0x42c1192927f6bdcf
+        .quad   0x8f91917a403d61ca
+        .quad   0xdc1c5a668b9e1f61
+        .quad   0x1596047804ec0f8d
+        .quad   0xecdfc35b48cade41
+        .quad   0x6a88471fb2328270
+        .quad   0x740a4a2440a01b6a
+        .quad   0x471e5796003b5f29
+        .quad   0xda96bbb3aced37ac
+        .quad   0x7a2423b5e9208cea
+        .quad   0x24cc5c3038aebae2
+        .quad   0x50c356afdc5dae2f
+
+        // 2^220 * 6 * B
+
+        .quad   0x09dcbf4341c30318
+        .quad   0xeeba061183181dce
+        .quad   0xc179c0cedc1e29a1
+        .quad   0x1dbf7b89073f35b0
+        .quad   0xcfed9cdf1b31b964
+        .quad   0xf486a9858ca51af3
+        .quad   0x14897265ea8c1f84
+        .quad   0x784a53dd932acc00
+        .quad   0x2d99f9df14fc4920
+        .quad   0x76ccb60cc4499fe5
+        .quad   0xa4132cbbe5cf0003
+        .quad   0x3f93d82354f000ea
+
+        // 2^220 * 7 * B
+
+        .quad   0x8183e7689e04ce85
+        .quad   0x678fb71e04465341
+        .quad   0xad92058f6688edac
+        .quad   0x5da350d3532b099a
+        .quad   0xeaac12d179e14978
+        .quad   0xff923ff3bbebff5e
+        .quad   0x4af663e40663ce27
+        .quad   0x0fd381a811a5f5ff
+        .quad   0xf256aceca436df54
+        .quad   0x108b6168ae69d6e8
+        .quad   0x20d986cb6b5d036c
+        .quad   0x655957b9fee2af50
+
+        // 2^220 * 8 * B
+
+        .quad   0xaea8b07fa902030f
+        .quad   0xf88c766af463d143
+        .quad   0x15b083663c787a60
+        .quad   0x08eab1148267a4a8
+        .quad   0xbdc1409bd002d0ac
+        .quad   0x66660245b5ccd9a6
+        .quad   0x82317dc4fade85ec
+        .quad   0x02fe934b6ad7df0d
+        .quad   0xef5cf100cfb7ea74
+        .quad   0x22897633a1cb42ac
+        .quad   0xd4ce0c54cef285e2
+        .quad   0x30408c048a146a55
+
+        // 2^224 * 1 * B
+
+        .quad   0x739d8845832fcedb
+        .quad   0xfa38d6c9ae6bf863
+        .quad   0x32bc0dcab74ffef7
+        .quad   0x73937e8814bce45e
+        .quad   0xbb2e00c9193b877f
+        .quad   0xece3a890e0dc506b
+        .quad   0xecf3b7c036de649f
+        .quad   0x5f46040898de9e1a
+        .quad   0xb9037116297bf48d
+        .quad   0xa9d13b22d4f06834
+        .quad   0xe19715574696bdc6
+        .quad   0x2cf8a4e891d5e835
+
+        // 2^224 * 2 * B
+
+        .quad   0x6d93fd8707110f67
+        .quad   0xdd4c09d37c38b549
+        .quad   0x7cb16a4cc2736a86
+        .quad   0x2049bd6e58252a09
+        .quad   0x2cb5487e17d06ba2
+        .quad   0x24d2381c3950196b
+        .quad   0xd7659c8185978a30
+        .quad   0x7a6f7f2891d6a4f6
+        .quad   0x7d09fd8d6a9aef49
+        .quad   0xf0ee60be5b3db90b
+        .quad   0x4c21b52c519ebfd4
+        .quad   0x6011aadfc545941d
+
+        // 2^224 * 3 * B
+
+        .quad   0x5f67926dcf95f83c
+        .quad   0x7c7e856171289071
+        .quad   0xd6a1e7f3998f7a5b
+        .quad   0x6fc5cc1b0b62f9e0
+        .quad   0x63ded0c802cbf890
+        .quad   0xfbd098ca0dff6aaa
+        .quad   0x624d0afdb9b6ed99
+        .quad   0x69ce18b779340b1e
+        .quad   0xd1ef5528b29879cb
+        .quad   0xdd1aae3cd47e9092
+        .quad   0x127e0442189f2352
+        .quad   0x15596b3ae57101f1
+
+        // 2^224 * 4 * B
+
+        .quad   0x462739d23f9179a2
+        .quad   0xff83123197d6ddcf
+        .quad   0x1307deb553f2148a
+        .quad   0x0d2237687b5f4dda
+        .quad   0x09ff31167e5124ca
+        .quad   0x0be4158bd9c745df
+        .quad   0x292b7d227ef556e5
+        .quad   0x3aa4e241afb6d138
+        .quad   0x2cc138bf2a3305f5
+        .quad   0x48583f8fa2e926c3
+        .quad   0x083ab1a25549d2eb
+        .quad   0x32fcaa6e4687a36c
+
+        // 2^224 * 5 * B
+
+        .quad   0x7bc56e8dc57d9af5
+        .quad   0x3e0bd2ed9df0bdf2
+        .quad   0xaac014de22efe4a3
+        .quad   0x4627e9cefebd6a5c
+        .quad   0x3207a4732787ccdf
+        .quad   0x17e31908f213e3f8
+        .quad   0xd5b2ecd7f60d964e
+        .quad   0x746f6336c2600be9
+        .quad   0x3f4af345ab6c971c
+        .quad   0xe288eb729943731f
+        .quad   0x33596a8a0344186d
+        .quad   0x7b4917007ed66293
+
+        // 2^224 * 6 * B
+
+        .quad   0x2d85fb5cab84b064
+        .quad   0x497810d289f3bc14
+        .quad   0x476adc447b15ce0c
+        .quad   0x122ba376f844fd7b
+        .quad   0x54341b28dd53a2dd
+        .quad   0xaa17905bdf42fc3f
+        .quad   0x0ff592d94dd2f8f4
+        .quad   0x1d03620fe08cd37d
+        .quad   0xc20232cda2b4e554
+        .quad   0x9ed0fd42115d187f
+        .quad   0x2eabb4be7dd479d9
+        .quad   0x02c70bf52b68ec4c
+
+        // 2^224 * 7 * B
+
+        .quad   0xa287ec4b5d0b2fbb
+        .quad   0x415c5790074882ca
+        .quad   0xe044a61ec1d0815c
+        .quad   0x26334f0a409ef5e0
+        .quad   0xace532bf458d72e1
+        .quad   0x5be768e07cb73cb5
+        .quad   0x56cf7d94ee8bbde7
+        .quad   0x6b0697e3feb43a03
+        .quad   0xb6c8f04adf62a3c0
+        .quad   0x3ef000ef076da45d
+        .quad   0x9c9cb95849f0d2a9
+        .quad   0x1cc37f43441b2fae
+
+        // 2^224 * 8 * B
+
+        .quad   0x508f565a5cc7324f
+        .quad   0xd061c4c0e506a922
+        .quad   0xfb18abdb5c45ac19
+        .quad   0x6c6809c10380314a
+        .quad   0xd76656f1c9ceaeb9
+        .quad   0x1c5b15f818e5656a
+        .quad   0x26e72832844c2334
+        .quad   0x3a346f772f196838
+        .quad   0xd2d55112e2da6ac8
+        .quad   0xe9bd0331b1e851ed
+        .quad   0x960746dd8ec67262
+        .quad   0x05911b9f6ef7c5d0
+
+        // 2^228 * 1 * B
+
+        .quad   0xe9dcd756b637ff2d
+        .quad   0xec4c348fc987f0c4
+        .quad   0xced59285f3fbc7b7
+        .quad   0x3305354793e1ea87
+        .quad   0x01c18980c5fe9f94
+        .quad   0xcd656769716fd5c8
+        .quad   0x816045c3d195a086
+        .quad   0x6e2b7f3266cc7982
+        .quad   0xcc802468f7c3568f
+        .quad   0x9de9ba8219974cb3
+        .quad   0xabb7229cb5b81360
+        .quad   0x44e2017a6fbeba62
+
+        // 2^228 * 2 * B
+
+        .quad   0xc4c2a74354dab774
+        .quad   0x8e5d4c3c4eaf031a
+        .quad   0xb76c23d242838f17
+        .quad   0x749a098f68dce4ea
+        .quad   0x87f82cf3b6ca6ecd
+        .quad   0x580f893e18f4a0c2
+        .quad   0x058930072604e557
+        .quad   0x6cab6ac256d19c1d
+        .quad   0xdcdfe0a02cc1de60
+        .quad   0x032665ff51c5575b
+        .quad   0x2c0c32f1073abeeb
+        .quad   0x6a882014cd7b8606
+
+        // 2^228 * 3 * B
+
+        .quad   0xa52a92fea4747fb5
+        .quad   0xdc12a4491fa5ab89
+        .quad   0xd82da94bb847a4ce
+        .quad   0x4d77edce9512cc4e
+        .quad   0xd111d17caf4feb6e
+        .quad   0x050bba42b33aa4a3
+        .quad   0x17514c3ceeb46c30
+        .quad   0x54bedb8b1bc27d75
+        .quad   0x77c8e14577e2189c
+        .quad   0xa3e46f6aff99c445
+        .quad   0x3144dfc86d335343
+        .quad   0x3a96559e7c4216a9
+
+        // 2^228 * 4 * B
+
+        .quad   0x12550d37f42ad2ee
+        .quad   0x8b78e00498a1fbf5
+        .quad   0x5d53078233894cb2
+        .quad   0x02c84e4e3e498d0c
+        .quad   0x4493896880baaa52
+        .quad   0x4c98afc4f285940e
+        .quad   0xef4aa79ba45448b6
+        .quad   0x5278c510a57aae7f
+        .quad   0xa54dd074294c0b94
+        .quad   0xf55d46b8df18ffb6
+        .quad   0xf06fecc58dae8366
+        .quad   0x588657668190d165
+
+        // 2^228 * 5 * B
+
+        .quad   0xd47712311aef7117
+        .quad   0x50343101229e92c7
+        .quad   0x7a95e1849d159b97
+        .quad   0x2449959b8b5d29c9
+        .quad   0xbf5834f03de25cc3
+        .quad   0xb887c8aed6815496
+        .quad   0x5105221a9481e892
+        .quad   0x6760ed19f7723f93
+        .quad   0x669ba3b7ac35e160
+        .quad   0x2eccf73fba842056
+        .quad   0x1aec1f17c0804f07
+        .quad   0x0d96bc031856f4e7
+
+        // 2^228 * 6 * B
+
+        .quad   0x3318be7775c52d82
+        .quad   0x4cb764b554d0aab9
+        .quad   0xabcf3d27cc773d91
+        .quad   0x3bf4d1848123288a
+        .quad   0xb1d534b0cc7505e1
+        .quad   0x32cd003416c35288
+        .quad   0xcb36a5800762c29d
+        .quad   0x5bfe69b9237a0bf8
+        .quad   0x183eab7e78a151ab
+        .quad   0xbbe990c999093763
+        .quad   0xff717d6e4ac7e335
+        .quad   0x4c5cddb325f39f88
+
+        // 2^228 * 7 * B
+
+        .quad   0xc0f6b74d6190a6eb
+        .quad   0x20ea81a42db8f4e4
+        .quad   0xa8bd6f7d97315760
+        .quad   0x33b1d60262ac7c21
+        .quad   0x57750967e7a9f902
+        .quad   0x2c37fdfc4f5b467e
+        .quad   0xb261663a3177ba46
+        .quad   0x3a375e78dc2d532b
+        .quad   0x8141e72f2d4dddea
+        .quad   0xe6eafe9862c607c8
+        .quad   0x23c28458573cafd0
+        .quad   0x46b9476f4ff97346
+
+        // 2^228 * 8 * B
+
+        .quad   0x0c1ffea44f901e5c
+        .quad   0x2b0b6fb72184b782
+        .quad   0xe587ff910114db88
+        .quad   0x37130f364785a142
+        .quad   0x1215505c0d58359f
+        .quad   0x2a2013c7fc28c46b
+        .quad   0x24a0a1af89ea664e
+        .quad   0x4400b638a1130e1f
+        .quad   0x3a01b76496ed19c3
+        .quad   0x31e00ab0ed327230
+        .quad   0x520a885783ca15b1
+        .quad   0x06aab9875accbec7
+
+        // 2^232 * 1 * B
+
+        .quad   0xc1339983f5df0ebb
+        .quad   0xc0f3758f512c4cac
+        .quad   0x2cf1130a0bb398e1
+        .quad   0x6b3cecf9aa270c62
+        .quad   0x5349acf3512eeaef
+        .quad   0x20c141d31cc1cb49
+        .quad   0x24180c07a99a688d
+        .quad   0x555ef9d1c64b2d17
+        .quad   0x36a770ba3b73bd08
+        .quad   0x624aef08a3afbf0c
+        .quad   0x5737ff98b40946f2
+        .quad   0x675f4de13381749d
+
+        // 2^232 * 2 * B
+
+        .quad   0x0e2c52036b1782fc
+        .quad   0x64816c816cad83b4
+        .quad   0xd0dcbdd96964073e
+        .quad   0x13d99df70164c520
+        .quad   0xa12ff6d93bdab31d
+        .quad   0x0725d80f9d652dfe
+        .quad   0x019c4ff39abe9487
+        .quad   0x60f450b882cd3c43
+        .quad   0x014b5ec321e5c0ca
+        .quad   0x4fcb69c9d719bfa2
+        .quad   0x4e5f1c18750023a0
+        .quad   0x1c06de9e55edac80
+
+        // 2^232 * 3 * B
+
+        .quad   0x990f7ad6a33ec4e2
+        .quad   0x6608f938be2ee08e
+        .quad   0x9ca143c563284515
+        .quad   0x4cf38a1fec2db60d
+        .quad   0xffd52b40ff6d69aa
+        .quad   0x34530b18dc4049bb
+        .quad   0x5e4a5c2fa34d9897
+        .quad   0x78096f8e7d32ba2d
+        .quad   0xa0aaaa650dfa5ce7
+        .quad   0xf9c49e2a48b5478c
+        .quad   0x4f09cc7d7003725b
+        .quad   0x373cad3a26091abe
+
+        // 2^232 * 4 * B
+
+        .quad   0xb294634d82c9f57c
+        .quad   0x1fcbfde124934536
+        .quad   0x9e9c4db3418cdb5a
+        .quad   0x0040f3d9454419fc
+        .quad   0xf1bea8fb89ddbbad
+        .quad   0x3bcb2cbc61aeaecb
+        .quad   0x8f58a7bb1f9b8d9d
+        .quad   0x21547eda5112a686
+        .quad   0xdefde939fd5986d3
+        .quad   0xf4272c89510a380c
+        .quad   0xb72ba407bb3119b9
+        .quad   0x63550a334a254df4
+
+        // 2^232 * 5 * B
+
+        .quad   0x6507d6edb569cf37
+        .quad   0x178429b00ca52ee1
+        .quad   0xea7c0090eb6bd65d
+        .quad   0x3eea62c7daf78f51
+        .quad   0x9bba584572547b49
+        .quad   0xf305c6fae2c408e0
+        .quad   0x60e8fa69c734f18d
+        .quad   0x39a92bafaa7d767a
+        .quad   0x9d24c713e693274e
+        .quad   0x5f63857768dbd375
+        .quad   0x70525560eb8ab39a
+        .quad   0x68436a0665c9c4cd
+
+        // 2^232 * 6 * B
+
+        .quad   0xbc0235e8202f3f27
+        .quad   0xc75c00e264f975b0
+        .quad   0x91a4e9d5a38c2416
+        .quad   0x17b6e7f68ab789f9
+        .quad   0x1e56d317e820107c
+        .quad   0xc5266844840ae965
+        .quad   0xc1e0a1c6320ffc7a
+        .quad   0x5373669c91611472
+        .quad   0x5d2814ab9a0e5257
+        .quad   0x908f2084c9cab3fc
+        .quad   0xafcaf5885b2d1eca
+        .quad   0x1cb4b5a678f87d11
+
+        // 2^232 * 7 * B
+
+        .quad   0xb664c06b394afc6c
+        .quad   0x0c88de2498da5fb1
+        .quad   0x4f8d03164bcad834
+        .quad   0x330bca78de7434a2
+        .quad   0x6b74aa62a2a007e7
+        .quad   0xf311e0b0f071c7b1
+        .quad   0x5707e438000be223
+        .quad   0x2dc0fd2d82ef6eac
+        .quad   0x982eff841119744e
+        .quad   0xf9695e962b074724
+        .quad   0xc58ac14fbfc953fb
+        .quad   0x3c31be1b369f1cf5
+
+        // 2^232 * 8 * B
+
+        .quad   0xb0f4864d08948aee
+        .quad   0x07dc19ee91ba1c6f
+        .quad   0x7975cdaea6aca158
+        .quad   0x330b61134262d4bb
+        .quad   0xc168bc93f9cb4272
+        .quad   0xaeb8711fc7cedb98
+        .quad   0x7f0e52aa34ac8d7a
+        .quad   0x41cec1097e7d55bb
+        .quad   0xf79619d7a26d808a
+        .quad   0xbb1fd49e1d9e156d
+        .quad   0x73d7c36cdba1df27
+        .quad   0x26b44cd91f28777d
+
+        // 2^236 * 1 * B
+
+        .quad   0x300a9035393aa6d8
+        .quad   0x2b501131a12bb1cd
+        .quad   0x7b1ff677f093c222
+        .quad   0x4309c1f8cab82bad
+        .quad   0xaf44842db0285f37
+        .quad   0x8753189047efc8df
+        .quad   0x9574e091f820979a
+        .quad   0x0e378d6069615579
+        .quad   0xd9fa917183075a55
+        .quad   0x4bdb5ad26b009fdc
+        .quad   0x7829ad2cd63def0e
+        .quad   0x078fc54975fd3877
+
+        // 2^236 * 2 * B
+
+        .quad   0x87dfbd1428878f2d
+        .quad   0x134636dd1e9421a1
+        .quad   0x4f17c951257341a3
+        .quad   0x5df98d4bad296cb8
+        .quad   0xe2004b5bb833a98a
+        .quad   0x44775dec2d4c3330
+        .quad   0x3aa244067eace913
+        .quad   0x272630e3d58e00a9
+        .quad   0xf3678fd0ecc90b54
+        .quad   0xf001459b12043599
+        .quad   0x26725fbc3758b89b
+        .quad   0x4325e4aa73a719ae
+
+        // 2^236 * 3 * B
+
+        .quad   0x657dc6ef433c3493
+        .quad   0x65375e9f80dbf8c3
+        .quad   0x47fd2d465b372dae
+        .quad   0x4966ab79796e7947
+        .quad   0xed24629acf69f59d
+        .quad   0x2a4a1ccedd5abbf4
+        .quad   0x3535ca1f56b2d67b
+        .quad   0x5d8c68d043b1b42d
+        .quad   0xee332d4de3b42b0a
+        .quad   0xd84e5a2b16a4601c
+        .quad   0x78243877078ba3e4
+        .quad   0x77ed1eb4184ee437
+
+        // 2^236 * 4 * B
+
+        .quad   0xbfd4e13f201839a0
+        .quad   0xaeefffe23e3df161
+        .quad   0xb65b04f06b5d1fe3
+        .quad   0x52e085fb2b62fbc0
+        .quad   0x185d43f89e92ed1a
+        .quad   0xb04a1eeafe4719c6
+        .quad   0x499fbe88a6f03f4f
+        .quad   0x5d8b0d2f3c859bdd
+        .quad   0x124079eaa54cf2ba
+        .quad   0xd72465eb001b26e7
+        .quad   0x6843bcfdc97af7fd
+        .quad   0x0524b42b55eacd02
+
+        // 2^236 * 5 * B
+
+        .quad   0xfd0d5dbee45447b0
+        .quad   0x6cec351a092005ee
+        .quad   0x99a47844567579cb
+        .quad   0x59d242a216e7fa45
+        .quad   0xbc18dcad9b829eac
+        .quad   0x23ae7d28b5f579d0
+        .quad   0xc346122a69384233
+        .quad   0x1a6110b2e7d4ac89
+        .quad   0x4f833f6ae66997ac
+        .quad   0x6849762a361839a4
+        .quad   0x6985dec1970ab525
+        .quad   0x53045e89dcb1f546
+
+        // 2^236 * 6 * B
+
+        .quad   0xcb8bb346d75353db
+        .quad   0xfcfcb24bae511e22
+        .quad   0xcba48d40d50ae6ef
+        .quad   0x26e3bae5f4f7cb5d
+        .quad   0x84da3cde8d45fe12
+        .quad   0xbd42c218e444e2d2
+        .quad   0xa85196781f7e3598
+        .quad   0x7642c93f5616e2b2
+        .quad   0x2323daa74595f8e4
+        .quad   0xde688c8b857abeb4
+        .quad   0x3fc48e961c59326e
+        .quad   0x0b2e73ca15c9b8ba
+
+        // 2^236 * 7 * B
+
+        .quad   0xd6bb4428c17f5026
+        .quad   0x9eb27223fb5a9ca7
+        .quad   0xe37ba5031919c644
+        .quad   0x21ce380db59a6602
+        .quad   0x0e3fbfaf79c03a55
+        .quad   0x3077af054cbb5acf
+        .quad   0xd5c55245db3de39f
+        .quad   0x015e68c1476a4af7
+        .quad   0xc1d5285220066a38
+        .quad   0x95603e523570aef3
+        .quad   0x832659a7226b8a4d
+        .quad   0x5dd689091f8eedc9
+
+        // 2^236 * 8 * B
+
+        .quad   0xcbac84debfd3c856
+        .quad   0x1624c348b35ff244
+        .quad   0xb7f88dca5d9cad07
+        .quad   0x3b0e574da2c2ebe8
+        .quad   0x1d022591a5313084
+        .quad   0xca2d4aaed6270872
+        .quad   0x86a12b852f0bfd20
+        .quad   0x56e6c439ad7da748
+        .quad   0xc704ff4942bdbae6
+        .quad   0x5e21ade2b2de1f79
+        .quad   0xe95db3f35652fad8
+        .quad   0x0822b5378f08ebc1
+
+        // 2^240 * 1 * B
+
+        .quad   0x51f048478f387475
+        .quad   0xb25dbcf49cbecb3c
+        .quad   0x9aab1244d99f2055
+        .quad   0x2c709e6c1c10a5d6
+        .quad   0xe1b7f29362730383
+        .quad   0x4b5279ffebca8a2c
+        .quad   0xdafc778abfd41314
+        .quad   0x7deb10149c72610f
+        .quad   0xcb62af6a8766ee7a
+        .quad   0x66cbec045553cd0e
+        .quad   0x588001380f0be4b5
+        .quad   0x08e68e9ff62ce2ea
+
+        // 2^240 * 2 * B
+
+        .quad   0x34ad500a4bc130ad
+        .quad   0x8d38db493d0bd49c
+        .quad   0xa25c3d98500a89be
+        .quad   0x2f1f3f87eeba3b09
+        .quad   0x2f2d09d50ab8f2f9
+        .quad   0xacb9218dc55923df
+        .quad   0x4a8f342673766cb9
+        .quad   0x4cb13bd738f719f5
+        .quad   0xf7848c75e515b64a
+        .quad   0xa59501badb4a9038
+        .quad   0xc20d313f3f751b50
+        .quad   0x19a1e353c0ae2ee8
+
+        // 2^240 * 3 * B
+
+        .quad   0x7d1c7560bafa05c3
+        .quad   0xb3e1a0a0c6e55e61
+        .quad   0xe3529718c0d66473
+        .quad   0x41546b11c20c3486
+        .quad   0xb42172cdd596bdbd
+        .quad   0x93e0454398eefc40
+        .quad   0x9fb15347b44109b5
+        .quad   0x736bd3990266ae34
+        .quad   0x85532d509334b3b4
+        .quad   0x46fd114b60816573
+        .quad   0xcc5f5f30425c8375
+        .quad   0x412295a2b87fab5c
+
+        // 2^240 * 4 * B
+
+        .quad   0x19c99b88f57ed6e9
+        .quad   0x5393cb266df8c825
+        .quad   0x5cee3213b30ad273
+        .quad   0x14e153ebb52d2e34
+        .quad   0x2e655261e293eac6
+        .quad   0x845a92032133acdb
+        .quad   0x460975cb7900996b
+        .quad   0x0760bb8d195add80
+        .quad   0x413e1a17cde6818a
+        .quad   0x57156da9ed69a084
+        .quad   0x2cbf268f46caccb1
+        .quad   0x6b34be9bc33ac5f2
+
+        // 2^240 * 5 * B
+
+        .quad   0xf3df2f643a78c0b2
+        .quad   0x4c3e971ef22e027c
+        .quad   0xec7d1c5e49c1b5a3
+        .quad   0x2012c18f0922dd2d
+        .quad   0x11fc69656571f2d3
+        .quad   0xc6c9e845530e737a
+        .quad   0xe33ae7a2d4fe5035
+        .quad   0x01b9c7b62e6dd30b
+        .quad   0x880b55e55ac89d29
+        .quad   0x1483241f45a0a763
+        .quad   0x3d36efdfc2e76c1f
+        .quad   0x08af5b784e4bade8
+
+        // 2^240 * 6 * B
+
+        .quad   0x283499dc881f2533
+        .quad   0x9d0525da779323b6
+        .quad   0x897addfb673441f4
+        .quad   0x32b79d71163a168d
+        .quad   0xe27314d289cc2c4b
+        .quad   0x4be4bd11a287178d
+        .quad   0x18d528d6fa3364ce
+        .quad   0x6423c1d5afd9826e
+        .quad   0xcc85f8d9edfcb36a
+        .quad   0x22bcc28f3746e5f9
+        .quad   0xe49de338f9e5d3cd
+        .quad   0x480a5efbc13e2dcc
+
+        // 2^240 * 7 * B
+
+        .quad   0x0b51e70b01622071
+        .quad   0x06b505cf8b1dafc5
+        .quad   0x2c6bb061ef5aabcd
+        .quad   0x47aa27600cb7bf31
+        .quad   0xb6614ce442ce221f
+        .quad   0x6e199dcc4c053928
+        .quad   0x663fb4a4dc1cbe03
+        .quad   0x24b31d47691c8e06
+        .quad   0x2a541eedc015f8c3
+        .quad   0x11a4fe7e7c693f7c
+        .quad   0xf0af66134ea278d6
+        .quad   0x545b585d14dda094
+
+        // 2^240 * 8 * B
+
+        .quad   0x67bf275ea0d43a0f
+        .quad   0xade68e34089beebe
+        .quad   0x4289134cd479e72e
+        .quad   0x0f62f9c332ba5454
+        .quad   0x6204e4d0e3b321e1
+        .quad   0x3baa637a28ff1e95
+        .quad   0x0b0ccffd5b99bd9e
+        .quad   0x4d22dc3e64c8d071
+        .quad   0xfcb46589d63b5f39
+        .quad   0x5cae6a3f57cbcf61
+        .quad   0xfebac2d2953afa05
+        .quad   0x1c0fa01a36371436
+
+        // 2^244 * 1 * B
+
+        .quad   0xe7547449bc7cd692
+        .quad   0x0f9abeaae6f73ddf
+        .quad   0x4af01ca700837e29
+        .quad   0x63ab1b5d3f1bc183
+        .quad   0xc11ee5e854c53fae
+        .quad   0x6a0b06c12b4f3ff4
+        .quad   0x33540f80e0b67a72
+        .quad   0x15f18fc3cd07e3ef
+        .quad   0x32750763b028f48c
+        .quad   0x06020740556a065f
+        .quad   0xd53bd812c3495b58
+        .quad   0x08706c9b865f508d
+
+        // 2^244 * 2 * B
+
+        .quad   0xf37ca2ab3d343dff
+        .quad   0x1a8c6a2d80abc617
+        .quad   0x8e49e035d4ccffca
+        .quad   0x48b46beebaa1d1b9
+        .quad   0xcc991b4138b41246
+        .quad   0x243b9c526f9ac26b
+        .quad   0xb9ef494db7cbabbd
+        .quad   0x5fba433dd082ed00
+        .quad   0x9c49e355c9941ad0
+        .quad   0xb9734ade74498f84
+        .quad   0x41c3fed066663e5c
+        .quad   0x0ecfedf8e8e710b3
+
+        // 2^244 * 3 * B
+
+        .quad   0x76430f9f9cd470d9
+        .quad   0xb62acc9ba42f6008
+        .quad   0x1898297c59adad5e
+        .quad   0x7789dd2db78c5080
+        .quad   0x744f7463e9403762
+        .quad   0xf79a8dee8dfcc9c9
+        .quad   0x163a649655e4cde3
+        .quad   0x3b61788db284f435
+        .quad   0xb22228190d6ef6b2
+        .quad   0xa94a66b246ce4bfa
+        .quad   0x46c1a77a4f0b6cc7
+        .quad   0x4236ccffeb7338cf
+
+        // 2^244 * 4 * B
+
+        .quad   0x8497404d0d55e274
+        .quad   0x6c6663d9c4ad2b53
+        .quad   0xec2fb0d9ada95734
+        .quad   0x2617e120cdb8f73c
+        .quad   0x3bd82dbfda777df6
+        .quad   0x71b177cc0b98369e
+        .quad   0x1d0e8463850c3699
+        .quad   0x5a71945b48e2d1f1
+        .quad   0x6f203dd5405b4b42
+        .quad   0x327ec60410b24509
+        .quad   0x9c347230ac2a8846
+        .quad   0x77de29fc11ffeb6a
+
+        // 2^244 * 5 * B
+
+        .quad   0xb0ac57c983b778a8
+        .quad   0x53cdcca9d7fe912c
+        .quad   0x61c2b854ff1f59dc
+        .quad   0x3a1a2cf0f0de7dac
+        .quad   0x835e138fecced2ca
+        .quad   0x8c9eaf13ea963b9a
+        .quad   0xc95fbfc0b2160ea6
+        .quad   0x575e66f3ad877892
+        .quad   0x99803a27c88fcb3a
+        .quad   0x345a6789275ec0b0
+        .quad   0x459789d0ff6c2be5
+        .quad   0x62f882651e70a8b2
+
+        // 2^244 * 6 * B
+
+        .quad   0x085ae2c759ff1be4
+        .quad   0x149145c93b0e40b7
+        .quad   0xc467e7fa7ff27379
+        .quad   0x4eeecf0ad5c73a95
+        .quad   0x6d822986698a19e0
+        .quad   0xdc9821e174d78a71
+        .quad   0x41a85f31f6cb1f47
+        .quad   0x352721c2bcda9c51
+        .quad   0x48329952213fc985
+        .quad   0x1087cf0d368a1746
+        .quad   0x8e5261b166c15aa5
+        .quad   0x2d5b2d842ed24c21
+
+        // 2^244 * 7 * B
+
+        .quad   0x02cfebd9ebd3ded1
+        .quad   0xd45b217739021974
+        .quad   0x7576f813fe30a1b7
+        .quad   0x5691b6f9a34ef6c2
+        .quad   0x5eb7d13d196ac533
+        .quad   0x377234ecdb80be2b
+        .quad   0xe144cffc7cf5ae24
+        .quad   0x5226bcf9c441acec
+        .quad   0x79ee6c7223e5b547
+        .quad   0x6f5f50768330d679
+        .quad   0xed73e1e96d8adce9
+        .quad   0x27c3da1e1d8ccc03
+
+        // 2^244 * 8 * B
+
+        .quad   0x7eb9efb23fe24c74
+        .quad   0x3e50f49f1651be01
+        .quad   0x3ea732dc21858dea
+        .quad   0x17377bd75bb810f9
+        .quad   0x28302e71630ef9f6
+        .quad   0xc2d4a2032b64cee0
+        .quad   0x090820304b6292be
+        .quad   0x5fca747aa82adf18
+        .quad   0x232a03c35c258ea5
+        .quad   0x86f23a2c6bcb0cf1
+        .quad   0x3dad8d0d2e442166
+        .quad   0x04a8933cab76862b
+
+        // 2^248 * 1 * B
+
+        .quad   0xd2c604b622943dff
+        .quad   0xbc8cbece44cfb3a0
+        .quad   0x5d254ff397808678
+        .quad   0x0fa3614f3b1ca6bf
+        .quad   0x69082b0e8c936a50
+        .quad   0xf9c9a035c1dac5b6
+        .quad   0x6fb73e54c4dfb634
+        .quad   0x4005419b1d2bc140
+        .quad   0xa003febdb9be82f0
+        .quad   0x2089c1af3a44ac90
+        .quad   0xf8499f911954fa8e
+        .quad   0x1fba218aef40ab42
+
+        // 2^248 * 2 * B
+
+        .quad   0xab549448fac8f53e
+        .quad   0x81f6e89a7ba63741
+        .quad   0x74fd6c7d6c2b5e01
+        .quad   0x392e3acaa8c86e42
+        .quad   0x4f3e57043e7b0194
+        .quad   0xa81d3eee08daaf7f
+        .quad   0xc839c6ab99dcdef1
+        .quad   0x6c535d13ff7761d5
+        .quad   0x4cbd34e93e8a35af
+        .quad   0x2e0781445887e816
+        .quad   0x19319c76f29ab0ab
+        .quad   0x25e17fe4d50ac13b
+
+        // 2^248 * 3 * B
+
+        .quad   0x0a289bd71e04f676
+        .quad   0x208e1c52d6420f95
+        .quad   0x5186d8b034691fab
+        .quad   0x255751442a9fb351
+        .quad   0x915f7ff576f121a7
+        .quad   0xc34a32272fcd87e3
+        .quad   0xccba2fde4d1be526
+        .quad   0x6bba828f8969899b
+        .quad   0xe2d1bc6690fe3901
+        .quad   0x4cb54a18a0997ad5
+        .quad   0x971d6914af8460d4
+        .quad   0x559d504f7f6b7be4
+
+        // 2^248 * 4 * B
+
+        .quad   0xa7738378b3eb54d5
+        .quad   0x1d69d366a5553c7c
+        .quad   0x0a26cf62f92800ba
+        .quad   0x01ab12d5807e3217
+        .quad   0x9c4891e7f6d266fd
+        .quad   0x0744a19b0307781b
+        .quad   0x88388f1d6061e23b
+        .quad   0x123ea6a3354bd50e
+        .quad   0x118d189041e32d96
+        .quad   0xb9ede3c2d8315848
+        .quad   0x1eab4271d83245d9
+        .quad   0x4a3961e2c918a154
+
+        // 2^248 * 5 * B
+
+        .quad   0x71dc3be0f8e6bba0
+        .quad   0xd6cef8347effe30a
+        .quad   0xa992425fe13a476a
+        .quad   0x2cd6bce3fb1db763
+        .quad   0x0327d644f3233f1e
+        .quad   0x499a260e34fcf016
+        .quad   0x83b5a716f2dab979
+        .quad   0x68aceead9bd4111f
+        .quad   0x38b4c90ef3d7c210
+        .quad   0x308e6e24b7ad040c
+        .quad   0x3860d9f1b7e73e23
+        .quad   0x595760d5b508f597
+
+        // 2^248 * 6 * B
+
+        .quad   0x6129bfe104aa6397
+        .quad   0x8f960008a4a7fccb
+        .quad   0x3f8bc0897d909458
+        .quad   0x709fa43edcb291a9
+        .quad   0x882acbebfd022790
+        .quad   0x89af3305c4115760
+        .quad   0x65f492e37d3473f4
+        .quad   0x2cb2c5df54515a2b
+        .quad   0xeb0a5d8c63fd2aca
+        .quad   0xd22bc1662e694eff
+        .quad   0x2723f36ef8cbb03a
+        .quad   0x70f029ecf0c8131f
+
+        // 2^248 * 7 * B
+
+        .quad   0x461307b32eed3e33
+        .quad   0xae042f33a45581e7
+        .quad   0xc94449d3195f0366
+        .quad   0x0b7d5d8a6c314858
+        .quad   0x2a6aafaa5e10b0b9
+        .quad   0x78f0a370ef041aa9
+        .quad   0x773efb77aa3ad61f
+        .quad   0x44eca5a2a74bd9e1
+        .quad   0x25d448327b95d543
+        .quad   0x70d38300a3340f1d
+        .quad   0xde1c531c60e1c52b
+        .quad   0x272224512c7de9e4
+
+        // 2^248 * 8 * B
+
+        .quad   0x1abc92af49c5342e
+        .quad   0xffeed811b2e6fad0
+        .quad   0xefa28c8dfcc84e29
+        .quad   0x11b5df18a44cc543
+        .quad   0xbf7bbb8a42a975fc
+        .quad   0x8c5c397796ada358
+        .quad   0xe27fc76fcdedaa48
+        .quad   0x19735fd7f6bc20a6
+        .quad   0xe3ab90d042c84266
+        .quad   0xeb848e0f7f19547e
+        .quad   0x2503a1d065a497b9
+        .quad   0x0fef911191df895f
diff --git a/cbits/s2n/arm/p256_montjadd.S b/cbits/s2n/arm/p256_montjadd.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjadd.S
@@ -0,0 +1,3165 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjadd(uint64_t p3[static 12], const uint64_t p1[static 12],
+//                              const uint64_t p2[static 12]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard ARM ABI: X0 = p3, X1 = p1, X2 = p2
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+// This is functionally equivalent to p256_montjadd in unopt/p256_montjadd.S.
+// This is the result of doing the following sequence of optimizations:
+//   1. Function inlining
+//   2. Eliminating redundant load/store instructions
+//   3. Folding (add addr, const) + load/store
+// Function inlining is done manually. The second and third optimizations are
+// done by a script.
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjadd)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjadd)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjadd)
+
+        .text
+        .balign 4
+
+#define NUMSIZE 32
+#define NSPACE NUMSIZE*7
+
+S2N_BN_SYMBOL(p256_montjadd):
+        CFI_START
+
+        CFI_PUSH2(x19,x20)
+        CFI_PUSH2(x21,x22)
+        CFI_PUSH2(x23,x24)
+        CFI_PUSH2(x25,x26)
+        CFI_PUSH2(x27,x30)
+        CFI_DEC_SP(NSPACE)
+
+        mov x21, x0
+        mov x22, x1
+        mov x23, x2
+        mov x0, sp
+        ldr q19, [x22, #64]
+        ldp x9, x13, [x22, #64]
+        ldr q23, [x22, #80]
+        ldr q0, [x22, #64]
+        ldp x1, x10, [x22, #80]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x19, x3, x16, cs
+        csel x14, x8, x14, cs
+        csel x12, x11, x12, cs
+        csel x20, x5, x2, cs
+        stp x14, x12, [x0, #16]
+        stp x19, x20, [x0]
+        ldr q19, [x23, #64]
+        ldp x9, x13, [x23, #64]
+        ldr q23, [x23, #80]
+        ldr q0, [x23, #64]
+        ldp x1, x10, [x23, #80]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x16, x3, x16, cs
+        csel x14, x8, x14, cs
+        csel x12, x11, x12, cs
+        csel x2, x5, x2, cs
+        stp x14, x12, [sp, #176]
+        stp x16, x2, [sp, #160]
+        ldr q20, [x22, #32]
+        ldp x7, x17, [x23, #64]
+        ldr q0, [x23, #64]
+        ldp x6, x10, [x22, #32]
+        ldp x11, x15, [x23, #80]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [x22, #48]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [x23, #80]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x22, #48]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x11, x11, x13
+        and x1, x1, x13
+        adcs x4, x4, x1
+        and x1, x12, x13
+        stp x11, x4, [sp, #192]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #208]
+        ldr q20, [x23, #32]
+        ldp x7, x17, [x22, #64]
+        ldr q0, [x22, #64]
+        ldp x6, x10, [x23, #32]
+        ldp x11, x15, [x22, #80]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [x23, #48]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [x22, #80]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x23, #48]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x24, x11, x13
+        and x1, x1, x13
+        adcs x25, x4, x1
+        and x1, x12, x13
+        stp x24, x25, [sp, #32]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #48]
+        mov x1, sp
+        ldr q20, [x23, #0]
+        ldr q0, [x1]
+        ldp x6, x10, [x23, #0]
+        ldp x11, x15, [x1, #16]
+        rev64 v16.4s, v20.4s
+        subs x4, x19, x20
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x20, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x19
+        ldr q20, [x23, #16]
+        sbcs x5, x15, x20
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x19, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [x1, #16]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x23, #16]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x11, x11, x13
+        and x1, x1, x13
+        adcs x4, x4, x1
+        and x1, x12, x13
+        stp x11, x4, [sp, #64]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #80]
+        ldr q20, [x22, #0]
+        ldp x7, x17, [sp, #160]
+        ldr q0, [sp, #160]
+        ldp x6, x10, [x22, #0]
+        ldp x11, x15, [sp, #176]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [x22, #16]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #176]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x22, #16]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x11, x11, x13
+        and x1, x1, x13
+        adcs x4, x4, x1
+        and x1, x12, x13
+        stp x11, x4, [sp, #128]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #144]
+        mov x1, sp
+        ldr q20, [sp, #32]
+        ldp x7, x17, [x1]
+        ldr q0, [x1]
+        ldp x11, x15, [x1, #16]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x25
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [sp, #48]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x24
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x25, x24
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [x1, #16]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #48]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x24, x7
+        sbcs x9, x25, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x24, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x25, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x24
+        eor x1, x10, x5
+        adcs x16, x2, x25
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x19, x11, x13
+        and x1, x1, x13
+        adcs x20, x4, x1
+        and x1, x12, x13
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #48]
+        ldr q20, [sp, #192]
+        ldp x7, x17, [sp, #160]
+        ldr q0, [sp, #160]
+        ldp x6, x10, [sp, #192]
+        ldp x11, x15, [sp, #176]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [sp, #208]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #176]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #208]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x9, x11, x13
+        and x1, x1, x13
+        adcs x10, x4, x1
+        and x1, x12, x13
+        stp x9, x10, [sp, #192]
+        adcs x11, x7, xzr
+        adc x12, x17, x1
+        stp x11, x12, [sp, #208]
+        ldp x5, x6, [sp, #64]
+        ldp x4, x3, [sp, #128]
+        subs x5, x5, x4
+        sbcs x6, x6, x3
+        ldp x7, x8, [sp, #80]
+        ldp x4, x3, [sp, #144]
+        sbcs x7, x7, x4
+        sbcs x8, x8, x3
+        csetm x3, cc
+        adds x13, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x24, x6, x4
+        adcs x25, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x26, x8, x4
+        stp x13, x24, [sp, #160]
+        stp x25, x26, [sp, #176]
+        subs x5, x19, x9
+        sbcs x6, x20, x10
+        ldp x7, x8, [sp, #48]
+        sbcs x7, x7, x11
+        sbcs x8, x8, x12
+        csetm x3, cc
+        adds x19, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x20, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x19, x20, [sp, #32]
+        stp x7, x8, [sp, #48]
+        ldr q19, [sp, #160]
+        ldr q23, [sp, #176]
+        ldr q0, [sp, #160]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x13, x24
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x13, x24
+        umulh x15, x13, x25
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x13, x24
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x26, x25
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x24, x26
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x25, x26
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x25, x26
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x26, x26
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x26, x26
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x25, x25
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x25, x25
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x24, x3, x16, cs
+        csel x25, x8, x14, cs
+        csel x26, x11, x12, cs
+        csel x27, x5, x2, cs
+        stp x25, x26, [sp, #112]
+        stp x24, x27, [sp, #96]
+        mov x0, sp
+        ldr q19, [sp, #32]
+        ldr q23, [sp, #48]
+        ldr q0, [sp, #32]
+        ldp x1, x10, [sp, #48]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x19, x20
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x19, x20
+        umulh x15, x19, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x19, x20
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x20, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x16, x3, x16, cs
+        csel x14, x8, x14, cs
+        csel x12, x11, x12, cs
+        csel x2, x5, x2, cs
+        stp x14, x12, [x0, #16]
+        stp x16, x2, [x0]
+        ldr q20, [sp, #128]
+        ldr q0, [sp, #96]
+        ldp x6, x10, [sp, #128]
+        rev64 v16.4s, v20.4s
+        subs x4, x24, x27
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x27, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x25, x24
+        ldr q20, [sp, #144]
+        sbcs x5, x26, x27
+        ngc x17, xzr
+        subs x8, x25, x26
+        uaddlp v27.2d, v16.4s
+        umulh x4, x24, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #112]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #144]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x25, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x26, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x25
+        eor x1, x10, x5
+        adcs x16, x2, x26
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x19, x11, x13
+        and x1, x1, x13
+        adcs x20, x4, x1
+        and x1, x12, x13
+        stp x19, x20, [sp, #128]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #144]
+        ldr q20, [sp, #64]
+        ldr q0, [sp, #96]
+        ldp x6, x10, [sp, #64]
+        ldp x11, x15, [sp, #112]
+        rev64 v16.4s, v20.4s
+        subs x4, x24, x27
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x27, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x24
+        ldr q20, [sp, #80]
+        sbcs x5, x15, x27
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x24, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #112]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #80]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x9, x11, x13
+        and x1, x1, x13
+        adcs x10, x4, x1
+        and x1, x12, x13
+        stp x9, x10, [sp, #64]
+        adcs x11, x7, xzr
+        adc x12, x17, x1
+        stp x11, x12, [sp, #80]
+        mov x0, sp
+        mov x1, sp
+        ldp x5, x6, [x1]
+        subs x5, x5, x19
+        sbcs x6, x6, x20
+        ldp x7, x8, [x1, #16]
+        ldp x4, x3, [sp, #144]
+        sbcs x7, x7, x4
+        sbcs x8, x8, x3
+        csetm x3, cc
+        adds x24, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x25, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x7, x8, [x0, #16]
+        subs x5, x9, x19
+        sbcs x6, x10, x20
+        ldp x4, x3, [sp, #144]
+        sbcs x7, x11, x4
+        sbcs x8, x12, x3
+        csetm x3, cc
+        adds x5, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x6, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x5, x6, [sp, #96]
+        stp x7, x8, [sp, #112]
+        ldr q20, [x22, #64]
+        ldp x7, x17, [sp, #160]
+        ldr q0, [sp, #160]
+        ldp x6, x10, [x22, #64]
+        ldp x11, x15, [sp, #176]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [x22, #80]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #176]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x22, #80]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x11, x11, x13
+        and x1, x1, x13
+        adcs x4, x4, x1
+        and x1, x12, x13
+        stp x11, x4, [sp, #160]
+        adcs x19, x7, xzr
+        adc x20, x17, x1
+        stp x19, x20, [sp, #176]
+        mov x0, sp
+        mov x1, sp
+        ldp x4, x3, [sp, #64]
+        subs x5, x24, x4
+        sbcs x6, x25, x3
+        ldp x7, x8, [x1, #16]
+        ldp x4, x3, [sp, #80]
+        sbcs x7, x7, x4
+        sbcs x8, x8, x3
+        csetm x3, cc
+        adds x9, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x10, x6, x4
+        adcs x11, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x3, x8, x4
+        stp x9, x10, [x0]
+        stp x11, x3, [x0, #16]
+        ldp x5, x6, [sp, #128]
+        subs x5, x5, x9
+        sbcs x6, x6, x10
+        ldp x7, x8, [sp, #144]
+        sbcs x7, x7, x11
+        sbcs x8, x8, x3
+        csetm x3, cc
+        adds x5, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x6, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x5, x6, [sp, #128]
+        stp x7, x8, [sp, #144]
+        ldr q20, [sp, #192]
+        ldp x7, x17, [sp, #96]
+        ldr q0, [sp, #96]
+        ldp x6, x10, [sp, #192]
+        ldp x11, x15, [sp, #112]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [sp, #208]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #112]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #208]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x11, x11, x13
+        and x1, x1, x13
+        adcs x4, x4, x1
+        and x1, x12, x13
+        stp x11, x4, [sp, #96]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #112]
+        ldr q20, [x23, #64]
+        ldp x7, x17, [sp, #160]
+        ldr q0, [sp, #160]
+        ldp x6, x10, [x23, #64]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x19, x7
+        ldr q20, [x23, #80]
+        sbcs x5, x20, x17
+        ngc x17, xzr
+        subs x8, x19, x20
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #176]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [x23, #80]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x19, x3, x13
+        adcs x20, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x24, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x25, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x19
+        adcs x15, x16, x20
+        eor x5, x17, x4
+        adcs x9, x1, x24
+        eor x1, x10, x5
+        adcs x16, x2, x25
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x19, x11, x13
+        and x1, x1, x13
+        adcs x20, x4, x1
+        and x1, x12, x13
+        stp x19, x20, [sp, #160]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #176]
+        ldr q20, [sp, #128]
+        ldp x7, x17, [sp, #32]
+        ldr q0, [sp, #32]
+        ldp x6, x10, [sp, #128]
+        ldp x11, x15, [sp, #48]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [sp, #144]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #48]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #144]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x24, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x24
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x5, x11, x13
+        and x1, x1, x13
+        adcs x6, x4, x1
+        and x1, x12, x13
+        adcs x7, x7, xzr
+        adc x9, x17, x1
+        ldp x4, x3, [sp, #96]
+        subs x5, x5, x4
+        sbcs x6, x6, x3
+        ldp x4, x3, [sp, #112]
+        sbcs x7, x7, x4
+        sbcs x8, x9, x3
+        csetm x3, cc
+        adds x15, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x24, x6, x4
+        adcs x25, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x26, x8, x4
+        stp x15, x24, [sp, #128]
+        stp x25, x26, [sp, #144]
+        ldp x0, x1, [x22, #64]
+        ldp x2, x3, [x22, #80]
+        orr x12, x0, x1
+        orr x13, x2, x3
+        orr x12, x12, x13
+        cmp x12, xzr
+        cset x12, ne
+        ldp x4, x5, [x23, #64]
+        ldp x6, x7, [x23, #80]
+        orr x13, x4, x5
+        orr x14, x6, x7
+        orr x13, x13, x14
+        cmp x13, xzr
+        cset x13, ne
+        cmp x13, x12
+        csel x8, x0, x19, cc
+        csel x9, x1, x20, cc
+        csel x8, x4, x8, hi
+        csel x9, x5, x9, hi
+        ldp x10, x11, [sp, #176]
+        csel x10, x2, x10, cc
+        csel x11, x3, x11, cc
+        csel x10, x6, x10, hi
+        csel x11, x7, x11, hi
+        ldp x12, x13, [x22]
+        ldp x0, x1, [sp]
+        csel x0, x12, x0, cc
+        csel x1, x13, x1, cc
+        ldp x12, x13, [x23]
+        csel x0, x12, x0, hi
+        csel x1, x13, x1, hi
+        ldp x12, x13, [x22, #16]
+        ldp x2, x3, [sp, #16]
+        csel x2, x12, x2, cc
+        csel x3, x13, x3, cc
+        ldp x12, x13, [x23, #16]
+        csel x2, x12, x2, hi
+        csel x3, x13, x3, hi
+        ldp x12, x13, [x22, #32]
+        csel x4, x12, x15, cc
+        csel x5, x13, x24, cc
+        ldp x12, x13, [x23, #32]
+        csel x4, x12, x4, hi
+        csel x5, x13, x5, hi
+        ldp x12, x13, [x22, #48]
+        csel x6, x12, x25, cc
+        csel x7, x13, x26, cc
+        ldp x12, x13, [x23, #48]
+        csel x6, x12, x6, hi
+        csel x7, x13, x7, hi
+        stp x0, x1, [x21]
+        stp x2, x3, [x21, #16]
+        stp x4, x5, [x21, #32]
+        stp x6, x7, [x21, #48]
+        stp x8, x9, [x21, #64]
+        stp x10, x11, [x21, #80]
+
+        CFI_INC_SP(NSPACE)
+        CFI_POP2(x27,x30)
+        CFI_POP2(x25,x26)
+        CFI_POP2(x23,x24)
+        CFI_POP2(x21,x22)
+        CFI_POP2(x19,x20)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjadd)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/arm/p256_montjadd_alt.S b/cbits/s2n/arm/p256_montjadd_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjadd_alt.S
@@ -0,0 +1,555 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjadd_alt(uint64_t p3[static 12],
+//                                  const uint64_t p1[static 12],
+//                                  const uint64_t p2[static 12]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard ARM ABI: X0 = p3, X1 = p1, X2 = p2
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjadd_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjadd_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjadd_alt)
+
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable homes for input arguments during main code sequence
+
+#define input_z x15
+#define input_x x16
+#define input_y x17
+
+// Pointer-offset pairs for inputs and outputs
+
+#define x_1 input_x, #0
+#define y_1 input_x, #NUMSIZE
+#define z_1 input_x, #(2*NUMSIZE)
+
+#define x_2 input_y, #0
+#define y_2 input_y, #NUMSIZE
+#define z_2 input_y, #(2*NUMSIZE)
+
+#define x_3 input_z, #0
+#define y_3 input_z, #NUMSIZE
+#define z_3 input_z, #(2*NUMSIZE)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// #NSPACE is the total stack needed for these temporaries
+
+#define z1sq sp, #(NUMSIZE*0)
+#define ww sp, #(NUMSIZE*0)
+#define resx sp, #(NUMSIZE*0)
+
+#define yd sp, #(NUMSIZE*1)
+#define y2a sp, #(NUMSIZE*1)
+
+#define x2a sp, #(NUMSIZE*2)
+#define zzx2 sp, #(NUMSIZE*2)
+
+#define zz sp, #(NUMSIZE*3)
+#define t1 sp, #(NUMSIZE*3)
+
+#define t2 sp, #(NUMSIZE*4)
+#define x1a sp, #(NUMSIZE*4)
+#define zzx1 sp, #(NUMSIZE*4)
+#define resy sp, #(NUMSIZE*4)
+
+#define xd sp, #(NUMSIZE*5)
+#define z2sq sp, #(NUMSIZE*5)
+#define resz sp, #(NUMSIZE*5)
+
+#define y1a sp, #(NUMSIZE*6)
+
+#define NSPACE NUMSIZE*7
+
+// Corresponds to bignum_montmul_p256_alt except registers
+
+#define montmul_p256(P0,P1,P2)                  \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        mul     x12, x3, x7 __LF                   \
+        umulh   x13, x3, x7 __LF                   \
+        mul     x11, x3, x8 __LF                   \
+        umulh   x14, x3, x8 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x9 __LF                   \
+        umulh   x0, x3, x9 __LF                    \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x3, x10 __LF                  \
+        umulh   x1, x3, x10 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x1, x1, xzr __LF                   \
+        ldp     x5, x6, [P1+16] __LF               \
+        mul     x11, x4, x7 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        mul     x11, x4, x8 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x4, x9 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x4, x10 __LF                  \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x3, x4, x10 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        umulh   x11, x4, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        umulh   x11, x4, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        umulh   x11, x4, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        mul     x11, x5, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        mul     x11, x5, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x5, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x5, x10 __LF                  \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x4, x5, x10 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        umulh   x11, x5, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        umulh   x11, x5, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x11, x5, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        mul     x11, x6, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        mul     x11, x6, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x6, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        mul     x11, x6, x10 __LF                  \
+        adcs    x4, x4, x11 __LF                   \
+        umulh   x5, x6, x10 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        mov     x10, #0xffffffff00000001 __LF      \
+        adds    x13, x13, x12, lsl #32 __LF        \
+        lsr     x11, x12, #32 __LF                 \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x12, x10 __LF                 \
+        umulh   x12, x12, x10 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x12, x12, xzr __LF                 \
+        umulh   x11, x6, x7 __LF                   \
+        adds    x1, x1, x11 __LF                   \
+        umulh   x11, x6, x8 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x11, x6, x9 __LF                   \
+        adcs    x4, x4, x11 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        adds    x14, x14, x13, lsl #32 __LF        \
+        lsr     x11, x13, #32 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x13, x10 __LF                 \
+        umulh   x13, x13, x10 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        adc     x13, x13, xzr __LF                 \
+        adds    x0, x0, x14, lsl #32 __LF          \
+        lsr     x11, x14, #32 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        mul     x11, x14, x10 __LF                 \
+        umulh   x14, x14, x10 __LF                 \
+        adcs    x13, x13, x11 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        adds    x12, x12, x0, lsl #32 __LF         \
+        lsr     x11, x0, #32 __LF                  \
+        adcs    x13, x13, x11 __LF                 \
+        mul     x11, x0, x10 __LF                  \
+        umulh   x0, x0, x10 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        adc     x0, x0, xzr __LF                   \
+        adds    x12, x12, x1 __LF                  \
+        adcs    x13, x13, x3 __LF                  \
+        adcs    x14, x14, x4 __LF                  \
+        adcs    x0, x0, x5 __LF                    \
+        cset    x8, cs __LF                        \
+        mov     x11, #0xffffffff __LF              \
+        adds    x1, x12, #0x1 __LF                 \
+        sbcs    x3, x13, x11 __LF                  \
+        sbcs    x4, x14, xzr __LF                  \
+        sbcs    x5, x0, x10 __LF                   \
+        sbcs    xzr, x8, xzr __LF                  \
+        csel    x12, x12, x1, cc __LF              \
+        csel    x13, x13, x3, cc __LF              \
+        csel    x14, x14, x4, cc __LF              \
+        csel    x0, x0, x5, cc __LF                \
+        stp     x12, x13, [P0] __LF                \
+        stp     x14, x0, [P0+16]
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        ldp     x2, x3, [P1] __LF                  \
+        mul     x9, x2, x3 __LF                    \
+        umulh   x10, x2, x3 __LF                   \
+        ldp     x4, x5, [P1+16] __LF               \
+        mul     x11, x2, x5 __LF                   \
+        umulh   x12, x2, x5 __LF                   \
+        mul     x6, x2, x4 __LF                    \
+        umulh   x7, x2, x4 __LF                    \
+        adds    x10, x10, x6 __LF                  \
+        adcs    x11, x11, x7 __LF                  \
+        mul     x6, x3, x4 __LF                    \
+        umulh   x7, x3, x4 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x11, x11, x6 __LF                  \
+        mul     x13, x4, x5 __LF                   \
+        umulh   x14, x4, x5 __LF                   \
+        adcs    x12, x12, x7 __LF                  \
+        mul     x6, x3, x5 __LF                    \
+        umulh   x7, x3, x5 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x12, x12, x6 __LF                  \
+        adcs    x13, x13, x7 __LF                  \
+        adc     x14, x14, xzr __LF                 \
+        adds    x9, x9, x9 __LF                    \
+        adcs    x10, x10, x10 __LF                 \
+        adcs    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adcs    x14, x14, x14 __LF                 \
+        cset    x7, cs __LF                        \
+        umulh   x6, x2, x2 __LF                    \
+        mul     x8, x2, x2 __LF                    \
+        adds    x9, x9, x6 __LF                    \
+        mul     x6, x3, x3 __LF                    \
+        adcs    x10, x10, x6 __LF                  \
+        umulh   x6, x3, x3 __LF                    \
+        adcs    x11, x11, x6 __LF                  \
+        mul     x6, x4, x4 __LF                    \
+        adcs    x12, x12, x6 __LF                  \
+        umulh   x6, x4, x4 __LF                    \
+        adcs    x13, x13, x6 __LF                  \
+        mul     x6, x5, x5 __LF                    \
+        adcs    x14, x14, x6 __LF                  \
+        umulh   x6, x5, x5 __LF                    \
+        adc     x7, x7, x6 __LF                    \
+        adds    x9, x9, x8, lsl #32 __LF           \
+        lsr     x3, x8, #32 __LF                   \
+        adcs    x10, x10, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x8, x3 __LF                    \
+        umulh   x8, x8, x3 __LF                    \
+        adcs    x11, x11, x2 __LF                  \
+        adc     x8, x8, xzr __LF                   \
+        adds    x10, x10, x9, lsl #32 __LF         \
+        lsr     x3, x9, #32 __LF                   \
+        adcs    x11, x11, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x9, x3 __LF                    \
+        umulh   x9, x9, x3 __LF                    \
+        adcs    x8, x8, x2 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x11, x11, x10, lsl #32 __LF        \
+        lsr     x3, x10, #32 __LF                  \
+        adcs    x8, x8, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x10, x3 __LF                   \
+        umulh   x10, x10, x3 __LF                  \
+        adcs    x9, x9, x2 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        adds    x8, x8, x11, lsl #32 __LF          \
+        lsr     x3, x11, #32 __LF                  \
+        adcs    x9, x9, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x11, x3 __LF                   \
+        umulh   x11, x11, x3 __LF                  \
+        adcs    x10, x10, x2 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x14 __LF                 \
+        adcs    x11, x11, x7 __LF                  \
+        cset    x2, cs __LF                        \
+        mov     x3, #0xffffffff __LF               \
+        mov     x5, #0xffffffff00000001 __LF       \
+        adds    x12, x8, #0x1 __LF                 \
+        sbcs    x13, x9, x3 __LF                   \
+        sbcs    x14, x10, xzr __LF                 \
+        sbcs    x7, x11, x5 __LF                   \
+        sbcs    xzr, x2, xzr __LF                  \
+        csel    x8, x8, x12, cc __LF               \
+        csel    x9, x9, x13, cc __LF               \
+        csel    x10, x10, x14, cc __LF             \
+        csel    x11, x11, x7, cc __LF              \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x11, [P0+16]
+
+// Almost-Montgomery variant which we use when an input to other muls
+// with the other argument fully reduced (which is always safe).
+
+#define amontsqr_p256(P0,P1)                    \
+        ldp     x2, x3, [P1] __LF                  \
+        mul     x9, x2, x3 __LF                    \
+        umulh   x10, x2, x3 __LF                   \
+        ldp     x4, x5, [P1+16] __LF               \
+        mul     x11, x2, x5 __LF                   \
+        umulh   x12, x2, x5 __LF                   \
+        mul     x6, x2, x4 __LF                    \
+        umulh   x7, x2, x4 __LF                    \
+        adds    x10, x10, x6 __LF                  \
+        adcs    x11, x11, x7 __LF                  \
+        mul     x6, x3, x4 __LF                    \
+        umulh   x7, x3, x4 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x11, x11, x6 __LF                  \
+        mul     x13, x4, x5 __LF                   \
+        umulh   x14, x4, x5 __LF                   \
+        adcs    x12, x12, x7 __LF                  \
+        mul     x6, x3, x5 __LF                    \
+        umulh   x7, x3, x5 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x12, x12, x6 __LF                  \
+        adcs    x13, x13, x7 __LF                  \
+        adc     x14, x14, xzr __LF                 \
+        adds    x9, x9, x9 __LF                    \
+        adcs    x10, x10, x10 __LF                 \
+        adcs    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adcs    x14, x14, x14 __LF                 \
+        cset    x7, cs __LF                        \
+        umulh   x6, x2, x2 __LF                    \
+        mul     x8, x2, x2 __LF                    \
+        adds    x9, x9, x6 __LF                    \
+        mul     x6, x3, x3 __LF                    \
+        adcs    x10, x10, x6 __LF                  \
+        umulh   x6, x3, x3 __LF                    \
+        adcs    x11, x11, x6 __LF                  \
+        mul     x6, x4, x4 __LF                    \
+        adcs    x12, x12, x6 __LF                  \
+        umulh   x6, x4, x4 __LF                    \
+        adcs    x13, x13, x6 __LF                  \
+        mul     x6, x5, x5 __LF                    \
+        adcs    x14, x14, x6 __LF                  \
+        umulh   x6, x5, x5 __LF                    \
+        adc     x7, x7, x6 __LF                    \
+        adds    x9, x9, x8, lsl #32 __LF           \
+        lsr     x3, x8, #32 __LF                   \
+        adcs    x10, x10, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x8, x3 __LF                    \
+        umulh   x8, x8, x3 __LF                    \
+        adcs    x11, x11, x2 __LF                  \
+        adc     x8, x8, xzr __LF                   \
+        adds    x10, x10, x9, lsl #32 __LF         \
+        lsr     x3, x9, #32 __LF                   \
+        adcs    x11, x11, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x9, x3 __LF                    \
+        umulh   x9, x9, x3 __LF                    \
+        adcs    x8, x8, x2 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x11, x11, x10, lsl #32 __LF        \
+        lsr     x3, x10, #32 __LF                  \
+        adcs    x8, x8, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x10, x3 __LF                   \
+        umulh   x10, x10, x3 __LF                  \
+        adcs    x9, x9, x2 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        adds    x8, x8, x11, lsl #32 __LF          \
+        lsr     x3, x11, #32 __LF                  \
+        adcs    x9, x9, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x11, x3 __LF                   \
+        umulh   x11, x11, x3 __LF                  \
+        adcs    x10, x10, x2 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x14 __LF                 \
+        adcs    x11, x11, x7 __LF                  \
+        mov     x2, #0xffffffffffffffff __LF       \
+        csel    x2, xzr, x2, cc __LF               \
+        mov     x3, #0xffffffff __LF               \
+        csel    x3, xzr, x3, cc __LF               \
+        mov     x5, #0xffffffff00000001 __LF       \
+        csel    x5, xzr, x5, cc __LF               \
+        subs    x8, x8, x2 __LF                    \
+        sbcs    x9, x9, x3 __LF                    \
+        sbcs    x10, x10, xzr __LF                 \
+        sbc     x11, x11, x5 __LF                  \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x11, [P0+16]
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        csetm   x3, cc __LF                        \
+        adds    x5, x5, x3 __LF                    \
+        mov     x4, #0xffffffff __LF               \
+        and     x4, x4, x3 __LF                    \
+        adcs    x6, x6, x4 __LF                    \
+        adcs    x7, x7, xzr __LF                   \
+        mov     x4, #0xffffffff00000001 __LF       \
+        and     x4, x4, x3 __LF                    \
+        adc     x8, x8, x4 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+S2N_BN_SYMBOL(p256_montjadd_alt):
+        CFI_START
+
+// Make room on stack for temporary variables
+// Move the input arguments to stable places
+
+        CFI_DEC_SP(NSPACE)
+
+        mov     input_z, x0
+        mov     input_x, x1
+        mov     input_y, x2
+
+// Main code, just a sequence of basic field operations
+// 12 * multiply + 4 * square + 7 * subtract
+
+        amontsqr_p256(z1sq,z_1)
+        amontsqr_p256(z2sq,z_2)
+
+        montmul_p256(y1a,z_2,y_1)
+        montmul_p256(y2a,z_1,y_2)
+
+        montmul_p256(x2a,z1sq,x_2)
+        montmul_p256(x1a,z2sq,x_1)
+        montmul_p256(y2a,z1sq,y2a)
+        montmul_p256(y1a,z2sq,y1a)
+
+        sub_p256(xd,x2a,x1a)
+        sub_p256(yd,y2a,y1a)
+
+        amontsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x1a)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(xd,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y1a)
+        montmul_p256(resz,xd,z_2)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Load in the z coordinates of the inputs to check for P1 = 0 and P2 = 0
+// The condition codes get set by a comparison (P2 != 0) - (P1 != 0)
+// So  "HI" <=> CF /\ ~ZF <=> P1 = 0 /\ ~(P2 = 0)
+// and "LO" <=> ~CF       <=> ~(P1 = 0) /\ P2 = 0
+
+        ldp     x0, x1, [z_1]
+        ldp     x2, x3, [z_1+16]
+
+        orr     x12, x0, x1
+        orr     x13, x2, x3
+        orr     x12, x12, x13
+        cmp     x12, xzr
+        cset    x12, ne
+
+        ldp     x4, x5, [z_2]
+        ldp     x6, x7, [z_2+16]
+
+        orr     x13, x4, x5
+        orr     x14, x6, x7
+        orr     x13, x13, x14
+        cmp     x13, xzr
+        cset    x13, ne
+
+        cmp     x13, x12
+
+// Multiplex the outputs accordingly, re-using the z's in registers
+
+        ldp     x8, x9, [resz]
+        csel    x8, x0, x8, lo
+        csel    x9, x1, x9, lo
+        csel    x8, x4, x8, hi
+        csel    x9, x5, x9, hi
+        ldp     x10, x11, [resz+16]
+        csel    x10, x2, x10, lo
+        csel    x11, x3, x11, lo
+        csel    x10, x6, x10, hi
+        csel    x11, x7, x11, hi
+
+        ldp     x12, x13, [x_1]
+        ldp     x0, x1, [resx]
+        csel    x0, x12, x0, lo
+        csel    x1, x13, x1, lo
+        ldp     x12, x13, [x_2]
+        csel    x0, x12, x0, hi
+        csel    x1, x13, x1, hi
+
+        ldp     x12, x13, [x_1+16]
+        ldp     x2, x3, [resx+16]
+        csel    x2, x12, x2, lo
+        csel    x3, x13, x3, lo
+        ldp     x12, x13, [x_2+16]
+        csel    x2, x12, x2, hi
+        csel    x3, x13, x3, hi
+
+        ldp     x12, x13, [y_1]
+        ldp     x4, x5, [resy]
+        csel    x4, x12, x4, lo
+        csel    x5, x13, x5, lo
+        ldp     x12, x13, [y_2]
+        csel    x4, x12, x4, hi
+        csel    x5, x13, x5, hi
+
+        ldp     x12, x13, [y_1+16]
+        ldp     x6, x7, [resy+16]
+        csel    x6, x12, x6, lo
+        csel    x7, x13, x7, lo
+        ldp     x12, x13, [y_2+16]
+        csel    x6, x12, x6, hi
+        csel    x7, x13, x7, hi
+
+// Finally store back the multiplexed values
+
+        stp     x0, x1, [x_3]
+        stp     x2, x3, [x_3+16]
+        stp     x4, x5, [y_3]
+        stp     x6, x7, [y_3+16]
+        stp     x8, x9, [z_3]
+        stp     x10, x11, [z_3+16]
+
+// Restore registers and return
+
+        CFI_INC_SP(NSPACE)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjadd_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/arm/p256_montjdouble.S b/cbits/s2n/arm/p256_montjdouble.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjdouble.S
@@ -0,0 +1,1555 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjdouble(uint64_t p3[static 12],
+//                                 const uint64_t p1[static 12]);
+//
+// Does p3 := 2 * p1 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard ARM ABI: X0 = p3, X1 = p1
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+// This is functionally equivalent to p256_montjdouble in unopt/p256_montjdouble.S.
+// This is the result of doing the following sequence of optimizations:
+//   1. Function inlining
+//   2. Eliminating redundant load/store instructions
+//   3. Folding (add addr, const) + load/store
+// Function inlining is done manually. The second and third optimizations are
+// done by a script.
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjdouble)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjdouble)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjdouble)
+        .text
+        .balign 4
+
+#define NUMSIZE 32
+#define NSPACE NUMSIZE*6
+
+S2N_BN_SYMBOL(p256_montjdouble):
+        CFI_START
+
+        CFI_DEC_SP(NSPACE+80)
+        CFI_STACKSAVE2(x19,x20,NSPACE)
+        CFI_STACKSAVE2(x21,x22,NSPACE+16)
+        CFI_STACKSAVE2(x23,x24,NSPACE+32)
+        CFI_STACKSAVE2(x25,x26,NSPACE+48)
+        CFI_STACKSAVE1Z(x27,NSPACE+64)
+
+        mov x19, x0
+        mov x20, x1
+        mov x0, sp
+        ldr q19, [x20, #64]
+        ldp x9, x13, [x20, #64]
+        ldr q23, [x20, #80]
+        ldr q0, [x20, #64]
+        ldp x1, x10, [x20, #80]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x21, x3, x16, cs
+        csel x22, x8, x14, cs
+        csel x23, x11, x12, cs
+        csel x24, x5, x2, cs
+        stp x22, x23, [x0, #16]
+        stp x21, x24, [x0]
+        ldr q19, [x20, #32]
+        ldp x9, x13, [x20, #32]
+        ldr q23, [x20, #48]
+        ldr q0, [x20, #32]
+        ldp x1, x10, [x20, #48]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x16, x3, x16, cs
+        csel x14, x8, x14, cs
+        csel x12, x11, x12, cs
+        csel x2, x5, x2, cs
+        stp x14, x12, [sp, #48]
+        stp x16, x2, [sp, #32]
+        ldp x5, x6, [x20, #0]
+        subs x5, x5, x21
+        sbcs x6, x6, x24
+        ldp x7, x8, [x20, #16]
+        sbcs x7, x7, x22
+        sbcs x8, x8, x23
+        csetm x3, cc
+        adds x10, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x25, x6, x4
+        adcs x26, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x27, x8, x4
+        stp x10, x25, [sp, #96]
+        stp x26, x27, [sp, #112]
+        ldp x5, x6, [x20]
+        adds x5, x5, x21
+        adcs x6, x6, x24
+        ldp x7, x8, [x20, #16]
+        adcs x7, x7, x22
+        adcs x8, x8, x23
+        csetm x3, cs
+        subs x9, x5, x3
+        and x1, x3, #0xffffffff
+        sbcs x5, x6, x1
+        sbcs x7, x7, xzr
+        and x2, x3, #0xffffffff00000001
+        sbc x8, x8, x2
+        stp x9, x5, [sp, #64]
+        stp x7, x8, [sp, #80]
+        ldr q20, [sp, #96]
+        ldr q0, [sp, #64]
+        rev64 v16.4s, v20.4s
+        subs x4, x9, x5
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x5, x25
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x7, x9
+        ldr q20, [sp, #112]
+        sbcs x5, x8, x5
+        ngc x17, xzr
+        subs x8, x7, x8
+        uaddlp v27.2d, v16.4s
+        umulh x4, x9, x10
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x25, x10
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #80]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x10, x26
+        sbcs x9, x25, x27
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x27, x26
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x21, x3, x13
+        adcs x22, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x23, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x24, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x21
+        adcs x15, x16, x22
+        eor x5, x17, x4
+        adcs x9, x1, x23
+        eor x1, x10, x5
+        adcs x16, x2, x24
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x21, x11, x13
+        and x1, x1, x13
+        adcs x22, x4, x1
+        and x1, x12, x13
+        stp x21, x22, [sp, #96]
+        adcs x23, x7, xzr
+        adc x24, x17, x1
+        stp x23, x24, [sp, #112]
+        ldp x4, x5, [x20, #32]
+        ldp x8, x9, [x20, #64]
+        adds x4, x4, x8
+        adcs x5, x5, x9
+        ldp x6, x7, [x20, #48]
+        ldp x10, x11, [x20, #80]
+        adcs x6, x6, x10
+        adcs x7, x7, x11
+        adc x3, xzr, xzr
+        adds x8, x4, #0x1
+        mov x9, #0xffffffff
+        sbcs x9, x5, x9
+        sbcs x10, x6, xzr
+        mov x11, #0xffffffff00000001
+        sbcs x11, x7, x11
+        sbcs x3, x3, xzr
+        csel x4, x4, x8, cc
+        csel x5, x5, x9, cc
+        csel x6, x6, x10, cc
+        csel x7, x7, x11, cc
+        stp x4, x5, [sp, #64]
+        stp x6, x7, [sp, #80]
+        ldr q20, [sp, #32]
+        ldp x7, x17, [x20, #0]
+        ldr q0, [x20, #0]
+        ldp x6, x10, [sp, #32]
+        ldp x11, x15, [x20, #16]
+        rev64 v16.4s, v20.4s
+        subs x4, x7, x17
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x17, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x11, x7
+        ldr q20, [sp, #48]
+        sbcs x5, x15, x17
+        ngc x17, xzr
+        subs x8, x11, x15
+        uaddlp v27.2d, v16.4s
+        umulh x4, x7, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [x20, #16]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #48]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x20, x3, x13
+        adcs x25, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x26, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x27, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x20
+        adcs x15, x16, x25
+        eor x5, x17, x4
+        adcs x9, x1, x26
+        eor x1, x10, x5
+        adcs x16, x2, x27
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x20, x11, x13
+        and x1, x1, x13
+        adcs x25, x4, x1
+        and x1, x12, x13
+        stp x20, x25, [sp, #128]
+        adcs x4, x7, xzr
+        adc x1, x17, x1
+        stp x4, x1, [sp, #144]
+        ldr q19, [sp, #96]
+        ldr q23, [sp, #112]
+        ldr q0, [sp, #96]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x21, x22
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x21, x22
+        umulh x15, x21, x23
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x21, x22
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x24, x23
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x22, x24
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x23, x24
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x23, x24
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x24, x24
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x24, x24
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x23, x23
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x23, x23
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x21, x3, x16, cs
+        csel x22, x8, x14, cs
+        csel x23, x11, x12, cs
+        csel x24, x5, x2, cs
+        ldr q19, [sp, #64]
+        ldp x9, x13, [sp, #64]
+        ldr q23, [sp, #80]
+        ldr q0, [sp, #64]
+        ldp x1, x10, [sp, #80]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x13, x3, x16, cs
+        csel x14, x8, x14, cs
+        csel x15, x11, x12, cs
+        csel x26, x5, x2, cs
+        mov x1, #0x9
+        mov x2, #0xffffffffffffffff
+        subs x9, x2, x21
+        mov x2, #0xffffffff
+        sbcs x10, x2, x24
+        ngcs x11, x22
+        mov x2, #0xffffffff00000001
+        sbc x12, x2, x23
+        mul x3, x1, x9
+        mul x4, x1, x10
+        mul x5, x1, x11
+        mul x6, x1, x12
+        umulh x9, x1, x9
+        umulh x10, x1, x10
+        umulh x11, x1, x11
+        umulh x7, x1, x12
+        adds x4, x4, x9
+        adcs x5, x5, x10
+        adcs x6, x6, x11
+        adc x7, x7, xzr
+        mov x1, #0xc
+        mul x8, x20, x1
+        umulh x9, x20, x1
+        adds x3, x3, x8
+        mul x8, x25, x1
+        umulh x10, x25, x1
+        adcs x4, x4, x8
+        ldp x11, x12, [sp, #144]
+        mul x8, x11, x1
+        umulh x11, x11, x1
+        adcs x5, x5, x8
+        mul x8, x12, x1
+        umulh x12, x12, x1
+        adcs x6, x6, x8
+        adc x7, x7, xzr
+        adds x4, x4, x9
+        adcs x5, x5, x10
+        adcs x6, x6, x11
+        adc x7, x7, x12
+        add x8, x7, #0x1
+        lsl x10, x8, #32
+        adds x6, x6, x10
+        adc x7, x7, xzr
+        neg x9, x8
+        sub x10, x10, #0x1
+        subs x3, x3, x9
+        sbcs x4, x4, x10
+        sbcs x5, x5, xzr
+        sbcs x6, x6, x8
+        sbc x8, x7, x8
+        adds x20, x3, x8
+        and x9, x8, #0xffffffff
+        adcs x21, x4, x9
+        adcs x22, x5, xzr
+        neg x10, x9
+        adc x23, x6, x10
+        stp x20, x21, [sp, #160]
+        stp x22, x23, [sp, #176]
+        mov x2, sp
+        ldp x4, x3, [x2]
+        subs x5, x13, x4
+        sbcs x6, x26, x3
+        ldp x4, x3, [x2, #16]
+        sbcs x7, x14, x4
+        sbcs x8, x15, x3
+        csetm x3, cc
+        adds x5, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x6, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x5, x6, [sp, #64]
+        stp x7, x8, [sp, #80]
+        mov x0, sp
+        ldr q19, [sp, #32]
+        ldp x9, x13, [sp, #32]
+        ldr q23, [sp, #48]
+        ldr q0, [sp, #32]
+        ldp x1, x10, [sp, #48]
+        uzp2 v29.4s, v19.4s, v19.4s
+        xtn v4.2s, v19.2d
+        umulh x8, x9, x13
+        rev64 v20.4s, v23.4s
+        umull v16.2d, v19.2s, v19.2s
+        umull v1.2d, v29.2s, v4.2s
+        mul v20.4s, v20.4s, v0.4s
+        subs x14, x9, x13
+        umulh x15, x9, x1
+        mov x16, v16.d[1]
+        umull2 v4.2d, v19.4s, v19.4s
+        mov x4, v16.d[0]
+        uzp1 v17.4s, v23.4s, v0.4s
+        uaddlp v19.2d, v20.4s
+        lsr x7, x8, #63
+        mul x11, x9, x13
+        mov x12, v1.d[0]
+        csetm x5, cc
+        cneg x6, x14, cc
+        mov x3, v4.d[1]
+        mov x14, v4.d[0]
+        subs x2, x10, x1
+        mov x9, v1.d[1]
+        cneg x17, x2, cc
+        cinv x2, x5, cc
+        adds x5, x4, x12, lsl #33
+        extr x4, x8, x11, #63
+        lsr x8, x12, #31
+        uzp1 v20.4s, v0.4s, v0.4s
+        shl v19.2d, v19.2d, #32
+        adc x16, x16, x8
+        adds x8, x14, x9, lsl #33
+        lsr x14, x9, #31
+        lsl x9, x5, #32
+        umlal v19.2d, v20.2s, v17.2s
+        adc x14, x3, x14
+        adds x16, x16, x11, lsl #1
+        lsr x3, x5, #32
+        umulh x12, x6, x17
+        adcs x4, x8, x4
+        adc x11, x14, x7
+        subs x8, x5, x9
+        sbc x5, x5, x3
+        adds x16, x16, x9
+        mov x14, v19.d[0]
+        mul x17, x6, x17
+        adcs x3, x4, x3
+        lsl x7, x16, #32
+        umulh x13, x13, x10
+        adcs x11, x11, x8
+        lsr x8, x16, #32
+        adc x5, x5, xzr
+        subs x9, x16, x7
+        sbc x16, x16, x8
+        adds x7, x3, x7
+        mov x3, v19.d[1]
+        adcs x6, x11, x8
+        umulh x11, x1, x10
+        adcs x5, x5, x9
+        eor x8, x12, x2
+        adc x9, x16, xzr
+        adds x16, x14, x15
+        adc x15, x15, xzr
+        adds x12, x16, x3
+        eor x16, x17, x2
+        mul x4, x1, x10
+        adcs x15, x15, x13
+        adc x17, x13, xzr
+        adds x15, x15, x3
+        adc x3, x17, xzr
+        cmn x2, #0x1
+        mul x17, x10, x10
+        adcs x12, x12, x16
+        adcs x16, x15, x8
+        umulh x10, x10, x10
+        adc x2, x3, x2
+        adds x14, x14, x14
+        adcs x12, x12, x12
+        adcs x16, x16, x16
+        adcs x2, x2, x2
+        adc x15, xzr, xzr
+        adds x14, x14, x7
+        mul x3, x1, x1
+        adcs x12, x12, x6
+        lsr x7, x14, #32
+        adcs x16, x16, x5
+        lsl x5, x14, #32
+        umulh x13, x1, x1
+        adcs x2, x2, x9
+        mov x6, #0xffffffff
+        adc x15, x15, xzr
+        adds x8, x4, x4
+        adcs x1, x11, x11
+        mov x11, #0xffffffff00000001
+        adc x4, xzr, xzr
+        subs x9, x14, x5
+        sbc x14, x14, x7
+        adds x12, x12, x5
+        adcs x16, x16, x7
+        lsl x5, x12, #32
+        lsr x7, x12, #32
+        adcs x2, x2, x9
+        adcs x14, x15, x14
+        adc x15, xzr, xzr
+        subs x9, x12, x5
+        sbc x12, x12, x7
+        adds x16, x16, x5
+        adcs x2, x2, x7
+        adcs x14, x14, x9
+        adcs x12, x15, x12
+        adc x15, xzr, xzr
+        adds x16, x16, x3
+        adcs x2, x2, x13
+        adcs x14, x14, x17
+        adcs x12, x12, x10
+        adc x15, x15, xzr
+        adds x2, x2, x8
+        adcs x14, x14, x1
+        adcs x12, x12, x4
+        adcs x15, x15, xzr
+        adds x3, x16, #0x1
+        sbcs x5, x2, x6
+        sbcs x8, x14, xzr
+        sbcs x11, x12, x11
+        sbcs xzr, x15, xzr
+        csel x24, x3, x16, cs
+        csel x25, x8, x14, cs
+        csel x26, x11, x12, cs
+        csel x27, x5, x2, cs
+        stp x25, x26, [x0, #16]
+        stp x24, x27, [x0]
+        ldr q20, [sp, #96]
+        ldr q0, [sp, #160]
+        ldp x6, x10, [sp, #96]
+        rev64 v16.4s, v20.4s
+        subs x4, x20, x21
+        csetm x3, cc
+        cneg x13, x4, cc
+        mul v16.4s, v16.4s, v0.4s
+        umulh x12, x21, x10
+        uzp1 v28.4s, v20.4s, v0.4s
+        subs x14, x22, x20
+        ldr q20, [sp, #112]
+        sbcs x5, x23, x21
+        ngc x17, xzr
+        subs x8, x22, x23
+        uaddlp v27.2d, v16.4s
+        umulh x4, x20, x6
+        uzp1 v21.4s, v0.4s, v0.4s
+        cneg x11, x8, cc
+        shl v17.2d, v27.2d, #32
+        csetm x15, cc
+        subs x9, x10, x6
+        eor x7, x14, x17
+        umlal v17.2d, v21.2s, v28.2s
+        cneg x8, x9, cc
+        cinv x9, x3, cc
+        cmn x17, #0x1
+        ldr q28, [sp, #176]
+        adcs x14, x7, xzr
+        mul x7, x13, x8
+        eor x1, x5, x17
+        adcs x5, x1, xzr
+        xtn v1.2s, v20.2d
+        mov x1, v17.d[0]
+        mov x3, v17.d[1]
+        uzp2 v16.4s, v20.4s, v20.4s
+        umulh x16, x13, x8
+        eor x13, x7, x9
+        adds x8, x1, x3
+        adcs x7, x4, x12
+        xtn v0.2s, v28.2d
+        adcs x12, x12, xzr
+        adds x8, x4, x8
+        adcs x3, x3, x7
+        ldp x7, x2, [sp, #112]
+        adcs x12, x12, xzr
+        cmn x9, #0x1
+        adcs x8, x8, x13
+        eor x13, x16, x9
+        adcs x16, x3, x13
+        lsl x3, x1, #32
+        adc x13, x12, x9
+        subs x12, x6, x7
+        sbcs x9, x10, x2
+        lsr x10, x1, #32
+        ngc x4, xzr
+        subs x6, x2, x7
+        cinv x2, x15, cc
+        cneg x6, x6, cc
+        subs x7, x1, x3
+        eor x9, x9, x4
+        sbc x1, x1, x10
+        adds x15, x8, x3
+        adcs x3, x16, x10
+        mul x16, x11, x6
+        adcs x8, x13, x7
+        eor x13, x12, x4
+        adc x10, x1, xzr
+        cmn x4, #0x1
+        umulh x6, x11, x6
+        adcs x11, x13, xzr
+        adcs x1, x9, xzr
+        lsl x13, x15, #32
+        subs x12, x15, x13
+        lsr x7, x15, #32
+        sbc x15, x15, x7
+        adds x20, x3, x13
+        adcs x21, x8, x7
+        umulh x8, x14, x11
+        umull v21.2d, v0.2s, v1.2s
+        adcs x22, x10, x12
+        umull v3.2d, v0.2s, v16.2s
+        adc x23, x15, xzr
+        rev64 v24.4s, v20.4s
+        movi v2.2d, #0xffffffff
+        mul x10, x14, x11
+        mul v4.4s, v24.4s, v28.4s
+        subs x13, x14, x5
+        uzp2 v19.4s, v28.4s, v28.4s
+        csetm x15, cc
+        usra v3.2d, v21.2d, #32
+        mul x7, x5, x1
+        umull v21.2d, v19.2s, v16.2s
+        cneg x13, x13, cc
+        uaddlp v5.2d, v4.4s
+        subs x11, x1, x11
+        and v16.16b, v3.16b, v2.16b
+        umulh x5, x5, x1
+        shl v24.2d, v5.2d, #32
+        cneg x11, x11, cc
+        umlal v16.2d, v19.2s, v1.2s
+        cinv x12, x15, cc
+        umlal v24.2d, v0.2s, v1.2s
+        adds x15, x10, x7
+        mul x14, x13, x11
+        eor x1, x6, x2
+        adcs x6, x8, x5
+        usra v21.2d, v3.2d, #32
+        adcs x9, x5, xzr
+        umulh x11, x13, x11
+        adds x15, x8, x15
+        adcs x7, x7, x6
+        eor x8, x14, x12
+        usra v21.2d, v16.2d, #32
+        adcs x13, x9, xzr
+        cmn x12, #0x1
+        mov x9, v24.d[1]
+        adcs x14, x15, x8
+        eor x6, x11, x12
+        adcs x6, x7, x6
+        mov x5, v24.d[0]
+        mov x11, v21.d[1]
+        mov x7, v21.d[0]
+        adc x3, x13, x12
+        adds x12, x5, x9
+        adcs x13, x7, x11
+        adcs x11, x11, xzr
+        adds x12, x7, x12
+        eor x16, x16, x2
+        adcs x7, x9, x13
+        adcs x11, x11, xzr
+        cmn x2, #0x1
+        adcs x16, x12, x16
+        adcs x1, x7, x1
+        adc x2, x11, x2
+        adds x7, x5, x20
+        adcs x15, x16, x21
+        eor x5, x17, x4
+        adcs x9, x1, x22
+        eor x1, x10, x5
+        adcs x16, x2, x23
+        adc x2, xzr, xzr
+        cmn x5, #0x1
+        eor x13, x14, x5
+        adcs x14, x1, x7
+        eor x1, x6, x5
+        adcs x6, x13, x15
+        adcs x10, x1, x9
+        eor x4, x3, x5
+        mov x1, #0xffffffff
+        adcs x8, x4, x16
+        lsr x13, x14, #32
+        adcs x17, x2, x5
+        adcs x11, x5, xzr
+        adc x4, x5, xzr
+        adds x12, x10, x7
+        adcs x7, x8, x15
+        adcs x5, x17, x9
+        adcs x9, x11, x16
+        lsl x11, x14, #32
+        adc x10, x4, x2
+        subs x17, x14, x11
+        sbc x4, x14, x13
+        adds x11, x6, x11
+        adcs x12, x12, x13
+        lsl x15, x11, #32
+        adcs x17, x7, x17
+        lsr x7, x11, #32
+        adc x13, x4, xzr
+        subs x4, x11, x15
+        sbc x11, x11, x7
+        adds x8, x12, x15
+        adcs x15, x17, x7
+        adcs x4, x13, x4
+        adc x11, x11, xzr
+        adds x7, x5, x4
+        adcs x17, x9, x11
+        adc x13, x10, xzr
+        add x12, x13, #0x1
+        neg x11, x12
+        lsl x4, x12, #32
+        adds x17, x17, x4
+        sub x4, x4, #0x1
+        adc x13, x13, xzr
+        subs x11, x8, x11
+        sbcs x4, x15, x4
+        sbcs x7, x7, xzr
+        sbcs x17, x17, x12
+        sbcs x13, x13, x12
+        mov x12, #0xffffffff00000001
+        adds x14, x11, x13
+        and x1, x1, x13
+        adcs x15, x4, x1
+        and x1, x12, x13
+        stp x14, x15, [sp, #96]
+        adcs x13, x7, xzr
+        adc x20, x17, x1
+        stp x13, x20, [sp, #112]
+        ldp x5, x6, [sp, #64]
+        ldp x4, x3, [sp, #32]
+        subs x5, x5, x4
+        sbcs x6, x6, x3
+        ldp x7, x8, [sp, #80]
+        ldp x4, x3, [sp, #48]
+        sbcs x7, x7, x4
+        sbcs x8, x8, x3
+        csetm x3, cc
+        adds x5, x5, x3
+        and x4, x3, #0xffffffff
+        adcs x6, x6, x4
+        adcs x7, x7, xzr
+        and x4, x3, #0xffffffff00000001
+        adc x8, x8, x4
+        stp x5, x6, [x19, #64]
+        stp x7, x8, [x19, #80]
+        ldp x1, x2, [sp, #128]
+        lsl x0, x1, #2
+        ldp x6, x7, [sp, #160]
+        subs x0, x0, x6
+        extr x1, x2, x1, #62
+        sbcs x1, x1, x7
+        ldp x3, x4, [sp, #144]
+        extr x2, x3, x2, #62
+        ldp x6, x7, [sp, #176]
+        sbcs x2, x2, x6
+        extr x3, x4, x3, #62
+        sbcs x3, x3, x7
+        lsr x4, x4, #62
+        sbc x4, x4, xzr
+        add x5, x4, #0x1
+        lsl x8, x5, #32
+        negs x6, x8
+        ngcs x7, xzr
+        sbc x8, x8, x5
+        adds x0, x0, x5
+        adcs x1, x1, x6
+        adcs x2, x2, x7
+        adcs x3, x3, x8
+        csetm x5, cc
+        adds x0, x0, x5
+        and x6, x5, #0xffffffff
+        adcs x1, x1, x6
+        adcs x2, x2, xzr
+        neg x7, x6
+        adc x3, x3, x7
+        stp x0, x1, [x19]
+        stp x2, x3, [x19, #16]
+        mov x2, #0xffffffffffffffff
+        subs x9, x2, x24
+        mov x2, #0xffffffff
+        sbcs x10, x2, x27
+        ngcs x11, x25
+        mov x2, #0xffffffff00000001
+        sbc x12, x2, x26
+        lsl x3, x9, #3
+        extr x4, x10, x9, #61
+        extr x5, x11, x10, #61
+        extr x6, x12, x11, #61
+        lsr x7, x12, #61
+        mov x1, #0x3
+        mul x8, x14, x1
+        umulh x9, x14, x1
+        adds x3, x3, x8
+        mul x8, x15, x1
+        umulh x10, x15, x1
+        adcs x4, x4, x8
+        mul x8, x13, x1
+        umulh x11, x13, x1
+        adcs x5, x5, x8
+        mul x8, x20, x1
+        umulh x12, x20, x1
+        adcs x6, x6, x8
+        adc x7, x7, xzr
+        adds x4, x4, x9
+        adcs x5, x5, x10
+        adcs x6, x6, x11
+        adc x7, x7, x12
+        add x8, x7, #0x1
+        lsl x10, x8, #32
+        adds x6, x6, x10
+        adc x7, x7, xzr
+        neg x9, x8
+        sub x10, x10, #0x1
+        subs x3, x3, x9
+        sbcs x4, x4, x10
+        sbcs x5, x5, xzr
+        sbcs x6, x6, x8
+        sbc x8, x7, x8
+        adds x3, x3, x8
+        and x9, x8, #0xffffffff
+        adcs x4, x4, x9
+        adcs x5, x5, xzr
+        neg x10, x9
+        adc x6, x6, x10
+        stp x3, x4, [x19, #32]
+        stp x5, x6, [x19, #48]
+
+        CFI_STACKLOAD1Z(x27,NSPACE+64)
+        CFI_STACKLOAD2(x25,x26,NSPACE+48)
+        CFI_STACKLOAD2(x23,x24,NSPACE+32)
+        CFI_STACKLOAD2(x21,x22,NSPACE+16)
+        CFI_STACKLOAD2(x19,x20,NSPACE)
+        CFI_INC_SP((NSPACE+80))
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjdouble)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/arm/p256_montjdouble_alt.S b/cbits/s2n/arm/p256_montjdouble_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjdouble_alt.S
@@ -0,0 +1,587 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjdouble_alt(uint64_t p3[static 12],
+//                                     const uint64_t p1[static 12]);
+//
+// Does p3 := 2 * p1 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard ARM ABI: X0 = p3, X1 = p1
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjdouble_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjdouble_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjdouble_alt)
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable homes for input arguments during main code sequence
+
+#define input_z x15
+#define input_x x16
+
+// Pointer-offset pairs for inputs and outputs
+
+#define x_1 input_x, #0
+#define y_1 input_x, #NUMSIZE
+#define z_1 input_x, #(2*NUMSIZE)
+
+#define x_3 input_z, #0
+#define y_3 input_z, #NUMSIZE
+#define z_3 input_z, #(2*NUMSIZE)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// #NSPACE is the total stack needed for these temporaries
+
+#define z2 sp, #(NUMSIZE*0)
+#define y4 sp, #(NUMSIZE*0)
+
+#define y2 sp, #(NUMSIZE*1)
+
+#define t1 sp, #(NUMSIZE*2)
+
+#define t2 sp, #(NUMSIZE*3)
+#define x2p sp, #(NUMSIZE*3)
+#define dx2 sp, #(NUMSIZE*3)
+
+#define xy2 sp, #(NUMSIZE*4)
+
+#define x4p sp, #(NUMSIZE*5)
+#define d sp, #(NUMSIZE*5)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds exactly to bignum_montmul_p256_alt except registers
+
+#define montmul_p256(P0,P1,P2)                  \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        mul     x12, x3, x7 __LF                   \
+        umulh   x13, x3, x7 __LF                   \
+        mul     x11, x3, x8 __LF                   \
+        umulh   x14, x3, x8 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x9 __LF                   \
+        umulh   x0, x3, x9 __LF                    \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x3, x10 __LF                  \
+        umulh   x1, x3, x10 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x1, x1, xzr __LF                   \
+        ldp     x5, x6, [P1+16] __LF               \
+        mul     x11, x4, x7 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        mul     x11, x4, x8 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x4, x9 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x4, x10 __LF                  \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x3, x4, x10 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        umulh   x11, x4, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        umulh   x11, x4, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        umulh   x11, x4, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        mul     x11, x5, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        mul     x11, x5, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x5, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x5, x10 __LF                  \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x4, x5, x10 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        umulh   x11, x5, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        umulh   x11, x5, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x11, x5, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        mul     x11, x6, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        mul     x11, x6, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x6, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        mul     x11, x6, x10 __LF                  \
+        adcs    x4, x4, x11 __LF                   \
+        umulh   x5, x6, x10 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        mov     x10, #0xffffffff00000001 __LF      \
+        adds    x13, x13, x12, lsl #32 __LF        \
+        lsr     x11, x12, #32 __LF                 \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x12, x10 __LF                 \
+        umulh   x12, x12, x10 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x12, x12, xzr __LF                 \
+        umulh   x11, x6, x7 __LF                   \
+        adds    x1, x1, x11 __LF                   \
+        umulh   x11, x6, x8 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x11, x6, x9 __LF                   \
+        adcs    x4, x4, x11 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        adds    x14, x14, x13, lsl #32 __LF        \
+        lsr     x11, x13, #32 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x13, x10 __LF                 \
+        umulh   x13, x13, x10 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        adc     x13, x13, xzr __LF                 \
+        adds    x0, x0, x14, lsl #32 __LF          \
+        lsr     x11, x14, #32 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        mul     x11, x14, x10 __LF                 \
+        umulh   x14, x14, x10 __LF                 \
+        adcs    x13, x13, x11 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        adds    x12, x12, x0, lsl #32 __LF         \
+        lsr     x11, x0, #32 __LF                  \
+        adcs    x13, x13, x11 __LF                 \
+        mul     x11, x0, x10 __LF                  \
+        umulh   x0, x0, x10 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        adc     x0, x0, xzr __LF                   \
+        adds    x12, x12, x1 __LF                  \
+        adcs    x13, x13, x3 __LF                  \
+        adcs    x14, x14, x4 __LF                  \
+        adcs    x0, x0, x5 __LF                    \
+        cset    x8, cs __LF                        \
+        mov     x11, #0xffffffff __LF              \
+        adds    x1, x12, #0x1 __LF                 \
+        sbcs    x3, x13, x11 __LF                  \
+        sbcs    x4, x14, xzr __LF                  \
+        sbcs    x5, x0, x10 __LF                   \
+        sbcs    xzr, x8, xzr __LF                  \
+        csel    x12, x12, x1, cc __LF              \
+        csel    x13, x13, x3, cc __LF              \
+        csel    x14, x14, x4, cc __LF              \
+        csel    x0, x0, x5, cc __LF                \
+        stp     x12, x13, [P0] __LF                \
+        stp     x14, x0, [P0+16]
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        ldp     x2, x3, [P1] __LF                  \
+        mul     x9, x2, x3 __LF                    \
+        umulh   x10, x2, x3 __LF                   \
+        ldp     x4, x5, [P1+16] __LF               \
+        mul     x11, x2, x5 __LF                   \
+        umulh   x12, x2, x5 __LF                   \
+        mul     x6, x2, x4 __LF                    \
+        umulh   x7, x2, x4 __LF                    \
+        adds    x10, x10, x6 __LF                  \
+        adcs    x11, x11, x7 __LF                  \
+        mul     x6, x3, x4 __LF                    \
+        umulh   x7, x3, x4 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x11, x11, x6 __LF                  \
+        mul     x13, x4, x5 __LF                   \
+        umulh   x14, x4, x5 __LF                   \
+        adcs    x12, x12, x7 __LF                  \
+        mul     x6, x3, x5 __LF                    \
+        umulh   x7, x3, x5 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x12, x12, x6 __LF                  \
+        adcs    x13, x13, x7 __LF                  \
+        adc     x14, x14, xzr __LF                 \
+        adds    x9, x9, x9 __LF                    \
+        adcs    x10, x10, x10 __LF                 \
+        adcs    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adcs    x14, x14, x14 __LF                 \
+        cset    x7, hs __LF                        \
+        umulh   x6, x2, x2 __LF                    \
+        mul     x8, x2, x2 __LF                    \
+        adds    x9, x9, x6 __LF                    \
+        mul     x6, x3, x3 __LF                    \
+        adcs    x10, x10, x6 __LF                  \
+        umulh   x6, x3, x3 __LF                    \
+        adcs    x11, x11, x6 __LF                  \
+        mul     x6, x4, x4 __LF                    \
+        adcs    x12, x12, x6 __LF                  \
+        umulh   x6, x4, x4 __LF                    \
+        adcs    x13, x13, x6 __LF                  \
+        mul     x6, x5, x5 __LF                    \
+        adcs    x14, x14, x6 __LF                  \
+        umulh   x6, x5, x5 __LF                    \
+        adc     x7, x7, x6 __LF                    \
+        mov     x5, #-4294967295 __LF              \
+        adds    x9, x9, x8, lsl #32 __LF           \
+        lsr     x3, x8, #32 __LF                   \
+        adcs    x10, x10, x3 __LF                  \
+        mul     x2, x8, x5 __LF                    \
+        umulh   x8, x8, x5 __LF                    \
+        adcs    x11, x11, x2 __LF                  \
+        adc     x8, x8, xzr __LF                   \
+        adds    x10, x10, x9, lsl #32 __LF         \
+        lsr     x3, x9, #32 __LF                   \
+        adcs    x11, x11, x3 __LF                  \
+        mul     x2, x9, x5 __LF                    \
+        umulh   x9, x9, x5 __LF                    \
+        adcs    x8, x8, x2 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x11, x11, x10, lsl #32 __LF        \
+        lsr     x3, x10, #32 __LF                  \
+        adcs    x8, x8, x3 __LF                    \
+        mul     x2, x10, x5 __LF                   \
+        umulh   x10, x10, x5 __LF                  \
+        adcs    x9, x9, x2 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        adds    x8, x8, x11, lsl #32 __LF          \
+        lsr     x3, x11, #32 __LF                  \
+        adcs    x9, x9, x3 __LF                    \
+        mul     x2, x11, x5 __LF                   \
+        umulh   x11, x11, x5 __LF                  \
+        adcs    x10, x10, x2 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x14 __LF                 \
+        adcs    x11, x11, x7 __LF                  \
+        cset    x2, hs __LF                        \
+        mov     x3, #4294967295 __LF               \
+        adds    x12, x8, #1 __LF                   \
+        sbcs    x13, x9, x3 __LF                   \
+        sbcs    x14, x10, xzr __LF                 \
+        sbcs    x7, x11, x5 __LF                   \
+        sbcs    xzr, x2, xzr __LF                  \
+        csel    x8, x8, x12, lo __LF               \
+        csel    x9, x9, x13, lo __LF               \
+        csel    x10, x10, x14, lo __LF             \
+        csel    x11, x11, x7, lo __LF              \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x11, [P0+16]
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        csetm   x3, lo __LF                        \
+        adds    x5, x5, x3 __LF                    \
+        and     x4, x3, #0xffffffff __LF           \
+        adcs    x6, x6, x4 __LF                    \
+        adcs    x7, x7, xzr __LF                   \
+        and     x4, x3, #0xffffffff00000001 __LF   \
+        adc     x8, x8, x4 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+// Corresponds exactly to bignum_add_p256
+
+#define add_p256(P0,P1,P2)                      \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        adds    x5, x5, x4 __LF                    \
+        adcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        adcs    x7, x7, x4 __LF                    \
+        adcs    x8, x8, x3 __LF                    \
+        adc     x3, xzr, xzr __LF                  \
+        cmn     x5, #1 __LF                        \
+        mov     x4, #4294967295 __LF               \
+        sbcs    xzr, x6, x4 __LF                   \
+        sbcs    xzr, x7, xzr __LF                  \
+        mov     x4, #-4294967295 __LF              \
+        sbcs    xzr, x8, x4 __LF                   \
+        adcs    x3, x3, xzr __LF                   \
+        csetm   x3, ne __LF                        \
+        subs    x5, x5, x3 __LF                    \
+        and     x4, x3, #0xffffffff __LF           \
+        sbcs    x6, x6, x4 __LF                    \
+        sbcs    x7, x7, xzr __LF                   \
+        and     x4, x3, #0xffffffff00000001 __LF   \
+        sbc     x8, x8, x4 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+// A weak version of add that only guarantees sum in 4 digits
+
+#define weakadd_p256(P0,P1,P2)                  \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        adds    x5, x5, x4 __LF                    \
+        adcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        adcs    x7, x7, x4 __LF                    \
+        adcs    x8, x8, x3 __LF                    \
+        csetm   x3, cs __LF                        \
+        subs    x5, x5, x3 __LF                    \
+        and     x1, x3, #4294967295 __LF           \
+        sbcs    x6, x6, x1 __LF                    \
+        sbcs    x7, x7, xzr __LF                   \
+        and     x2, x3, #-4294967295 __LF          \
+        sbc     x8, x8, x2 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+// P0 = C * P1 - D * P2 computed as D * (p_256 - P2) + C * P1
+// Quotient estimation is done just as q = h + 1 as in bignum_triple_p256
+// This also applies to the other functions following.
+
+#define cmsub_p256(P0,C,P1,D,P2)                \
+        mov     x1, D __LF                         \
+        mov     x2, #-1 __LF                       \
+        ldp     x9, x10, [P2] __LF                 \
+        subs    x9, x2, x9 __LF                    \
+        mov     x2, #4294967295 __LF               \
+        sbcs    x10, x2, x10 __LF                  \
+        ldp     x11, x12, [P2+16] __LF             \
+        sbcs    x11, xzr, x11 __LF                 \
+        mov     x2, #-4294967295 __LF              \
+        sbc     x12, x2, x12 __LF                  \
+        mul     x3, x1, x9 __LF                    \
+        mul     x4, x1, x10 __LF                   \
+        mul     x5, x1, x11 __LF                   \
+        mul     x6, x1, x12 __LF                   \
+        umulh   x9, x1, x9 __LF                    \
+        umulh   x10, x1, x10 __LF                  \
+        umulh   x11, x1, x11 __LF                  \
+        umulh   x7, x1, x12 __LF                   \
+        adds    x4, x4, x9 __LF                    \
+        adcs    x5, x5, x10 __LF                   \
+        adcs    x6, x6, x11 __LF                   \
+        adc     x7, x7, xzr __LF                   \
+        mov     x1, C __LF                         \
+        ldp     x9, x10, [P1] __LF                 \
+        mul     x8, x9, x1 __LF                    \
+        umulh   x9, x9, x1 __LF                    \
+        adds    x3, x3, x8 __LF                    \
+        mul     x8, x10, x1 __LF                   \
+        umulh   x10, x10, x1 __LF                  \
+        adcs    x4, x4, x8 __LF                    \
+        ldp     x11, x12, [P1+16] __LF             \
+        mul     x8, x11, x1 __LF                   \
+        umulh   x11, x11, x1 __LF                  \
+        adcs    x5, x5, x8 __LF                    \
+        mul     x8, x12, x1 __LF                   \
+        umulh   x12, x12, x1 __LF                  \
+        adcs    x6, x6, x8 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x4, x4, x9 __LF                    \
+        adcs    x5, x5, x10 __LF                   \
+        adcs    x6, x6, x11 __LF                   \
+        adc     x7, x7, x12 __LF                   \
+        add     x8, x7, #1 __LF                    \
+        lsl     x10, x8, #32 __LF                  \
+        adds    x6, x6, x10 __LF                   \
+        adc     x7, x7, xzr __LF                   \
+        neg     x9, x8 __LF                        \
+        sub     x10, x10, #1 __LF                  \
+        subs    x3, x3, x9 __LF                    \
+        sbcs    x4, x4, x10 __LF                   \
+        sbcs    x5, x5, xzr __LF                   \
+        sbcs    x6, x6, x8 __LF                    \
+        sbc     x8, x7, x8 __LF                    \
+        adds    x3, x3, x8 __LF                    \
+        and     x9, x8, #4294967295 __LF           \
+        adcs    x4, x4, x9 __LF                    \
+        adcs    x5, x5, xzr __LF                   \
+        neg     x10, x9 __LF                       \
+        adc     x6, x6, x10 __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+// P0 = 4 * P1 - P2, by direct subtraction of P2; the method
+// in bignum_cmul_p256 etc. for quotient estimation still
+// works when the value to be reduced is negative, as
+// long as it is  > -p_256, which is the case here. The
+// actual accumulation of q * p_256 is done a bit differently
+// so it works for the q = 0 case.
+
+#define cmsub41_p256(P0,P1,P2)                  \
+        ldp     x1, x2, [P1] __LF                  \
+        lsl     x0, x1, #2 __LF                    \
+        ldp     x6, x7, [P2] __LF                  \
+        subs    x0, x0, x6 __LF                    \
+        extr    x1, x2, x1, #62 __LF               \
+        sbcs    x1, x1, x7 __LF                    \
+        ldp     x3, x4, [P1+16] __LF               \
+        extr    x2, x3, x2, #62 __LF               \
+        ldp     x6, x7, [P2+16] __LF               \
+        sbcs    x2, x2, x6 __LF                    \
+        extr    x3, x4, x3, #62 __LF               \
+        sbcs    x3, x3, x7 __LF                    \
+        lsr     x4, x4, #62 __LF                   \
+        sbc     x4, x4, xzr __LF                   \
+        add     x5, x4, #1 __LF                    \
+        lsl     x8, x5, #32 __LF                   \
+        subs    x6, xzr, x8 __LF                   \
+        sbcs    x7, xzr, xzr __LF                  \
+        sbc     x8, x8, x5 __LF                    \
+        adds    x0, x0, x5 __LF                    \
+        adcs    x1, x1, x6 __LF                    \
+        adcs    x2, x2, x7 __LF                    \
+        adcs    x3, x3, x8 __LF                    \
+        csetm   x5, cc __LF                        \
+        adds    x0, x0, x5 __LF                    \
+        and     x6, x5, #4294967295 __LF           \
+        adcs    x1, x1, x6 __LF                    \
+        adcs    x2, x2, xzr __LF                   \
+        neg     x7, x6 __LF                        \
+        adc     x3, x3, x7 __LF                    \
+        stp     x0, x1, [P0] __LF                  \
+        stp     x2, x3, [P0+16]
+
+// P0 = 3 * P1 - 8 * P2, computed as (p_256 - P2) << 3 + 3 * P1
+
+#define cmsub38_p256(P0,P1,P2)                  \
+        mov     x1, 8 __LF                         \
+        mov     x2, #-1 __LF                       \
+        ldp     x9, x10, [P2] __LF                 \
+        subs    x9, x2, x9 __LF                    \
+        mov     x2, #4294967295 __LF               \
+        sbcs    x10, x2, x10 __LF                  \
+        ldp     x11, x12, [P2+16] __LF             \
+        sbcs    x11, xzr, x11 __LF                 \
+        mov     x2, #-4294967295 __LF              \
+        sbc     x12, x2, x12 __LF                  \
+        lsl     x3, x9, #3 __LF                    \
+        extr    x4, x10, x9, #61 __LF              \
+        extr    x5, x11, x10, #61 __LF             \
+        extr    x6, x12, x11, #61 __LF             \
+        lsr     x7, x12, #61 __LF                  \
+        mov     x1, 3 __LF                         \
+        ldp     x9, x10, [P1] __LF                 \
+        mul     x8, x9, x1 __LF                    \
+        umulh   x9, x9, x1 __LF                    \
+        adds    x3, x3, x8 __LF                    \
+        mul     x8, x10, x1 __LF                   \
+        umulh   x10, x10, x1 __LF                  \
+        adcs    x4, x4, x8 __LF                    \
+        ldp     x11, x12, [P1+16] __LF             \
+        mul     x8, x11, x1 __LF                   \
+        umulh   x11, x11, x1 __LF                  \
+        adcs    x5, x5, x8 __LF                    \
+        mul     x8, x12, x1 __LF                   \
+        umulh   x12, x12, x1 __LF                  \
+        adcs    x6, x6, x8 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x4, x4, x9 __LF                    \
+        adcs    x5, x5, x10 __LF                   \
+        adcs    x6, x6, x11 __LF                   \
+        adc     x7, x7, x12 __LF                   \
+        add     x8, x7, #1 __LF                    \
+        lsl     x10, x8, #32 __LF                  \
+        adds    x6, x6, x10 __LF                   \
+        adc     x7, x7, xzr __LF                   \
+        neg     x9, x8 __LF                        \
+        sub     x10, x10, #1 __LF                  \
+        subs    x3, x3, x9 __LF                    \
+        sbcs    x4, x4, x10 __LF                   \
+        sbcs    x5, x5, xzr __LF                   \
+        sbcs    x6, x6, x8 __LF                    \
+        sbc     x8, x7, x8 __LF                    \
+        adds    x3, x3, x8 __LF                    \
+        and     x9, x8, #4294967295 __LF           \
+        adcs    x4, x4, x9 __LF                    \
+        adcs    x5, x5, xzr __LF                   \
+        neg     x10, x9 __LF                       \
+        adc     x6, x6, x10 __LF                   \
+        stp     x3, x4, [P0] __LF                  \
+        stp     x5, x6, [P0+16]
+
+S2N_BN_SYMBOL(p256_montjdouble_alt):
+        CFI_START
+
+// Make room on stack for temporary variables
+
+        CFI_DEC_SP(NSPACE)
+
+// Move the input arguments to stable places
+
+        mov     input_z, x0
+        mov     input_x, x1
+
+// Main code, just a sequence of basic field operations
+
+// z2 = z^2
+// y2 = y^2
+
+        montsqr_p256(z2,z_1)
+        montsqr_p256(y2,y_1)
+
+// x2p = x^2 - z^4 = (x + z^2) * (x - z^2)
+
+        sub_p256(t2,x_1,z2)
+        weakadd_p256(t1,x_1,z2)
+        montmul_p256(x2p,t1,t2)
+
+// t1 = y + z
+// xy2 = x * y^2
+// x4p = x2p^2
+
+        add_p256(t1,y_1,z_1)
+        montmul_p256(xy2,x_1,y2)
+        montsqr_p256(x4p,x2p)
+
+// t1 = (y + z)^2
+
+        montsqr_p256(t1,t1)
+
+// d = 12 * xy2 - 9 * x4p
+// t1 = y^2 + 2 * y * z
+
+        cmsub_p256(d,12,xy2,9,x4p)
+        sub_p256(t1,t1,z2)
+
+// y4 = y^4
+
+        montsqr_p256(y4,y2)
+
+// dx2 = d * x2p
+
+        montmul_p256(dx2,d,x2p)
+
+// z_3' = 2 * y * z
+
+        sub_p256(z_3,t1,y2)
+
+// x' = 4 * xy2 - d
+
+        cmsub41_p256(x_3,xy2,d)
+
+// y' = 3 * dx2 - 8 * y4
+
+        cmsub38_p256(y_3,dx2,y4)
+
+// Restore stack and return
+
+        CFI_INC_SP(NSPACE)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjdouble_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/arm/p256_montjmixadd.S b/cbits/s2n/arm/p256_montjmixadd.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjmixadd.S
@@ -0,0 +1,513 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjmixadd(uint64_t p3[static 12],
+//                                 const uint64_t p1[static 12],
+//                                 const uint64_t p2[static 8]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+// The "mixed" part means that p2 only has x and y coordinates, with the
+// implicit z coordinate assumed to be the identity.
+//
+// Standard ARM ABI: X0 = p3, X1 = p1, X2 = p2
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjmixadd)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjmixadd)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjmixadd)
+
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable homes for input arguments during main code sequence
+
+#define input_z x17
+#define input_x x19
+#define input_y x20
+
+// Pointer-offset pairs for inputs and outputs
+
+#define x_1 input_x, #0
+#define y_1 input_x, #NUMSIZE
+#define z_1 input_x, #(2*NUMSIZE)
+
+#define x_2 input_y, #0
+#define y_2 input_y, #NUMSIZE
+
+#define x_3 input_z, #0
+#define y_3 input_z, #NUMSIZE
+#define z_3 input_z, #(2*NUMSIZE)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// #NSPACE is the total stack needed for these temporaries
+
+#define zp2 sp, #(NUMSIZE*0)
+#define ww sp, #(NUMSIZE*0)
+#define resx sp, #(NUMSIZE*0)
+
+#define yd sp, #(NUMSIZE*1)
+#define y2a sp, #(NUMSIZE*1)
+
+#define x2a sp, #(NUMSIZE*2)
+#define zzx2 sp, #(NUMSIZE*2)
+
+#define zz sp, #(NUMSIZE*3)
+#define t1 sp, #(NUMSIZE*3)
+
+#define t2 sp, #(NUMSIZE*4)
+#define zzx1 sp, #(NUMSIZE*4)
+#define resy sp, #(NUMSIZE*4)
+
+#define xd sp, #(NUMSIZE*5)
+#define resz sp, #(NUMSIZE*5)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds to bignum_montmul_p256 but uses x0 in place of x17
+
+#define montmul_p256(P0,P1,P2)                  \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x5, x6, [P1+16] __LF               \
+        ldp     x7, x8, [P2] __LF                  \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x7 __LF                   \
+        mul     x13, x4, x8 __LF                   \
+        umulh   x12, x3, x7 __LF                   \
+        adds    x16, x11, x13 __LF                 \
+        umulh   x14, x4, x8 __LF                   \
+        adcs    x0, x12, x14 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        adds    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        subs    x15, x3, x4 __LF                   \
+        cneg    x15, x15, lo __LF                  \
+        csetm   x1, lo __LF                        \
+        subs    x0, x8, x7 __LF                    \
+        cneg    x0, x0, lo __LF                    \
+        mul     x16, x15, x0 __LF                  \
+        umulh   x0, x15, x0 __LF                   \
+        cinv    x1, x1, lo __LF                    \
+        eor     x16, x16, x1 __LF                  \
+        eor     x0, x0, x1 __LF                    \
+        cmn     x1, #1 __LF                        \
+        adcs    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adc     x14, x14, x1 __LF                  \
+        lsl     x0, x11, #32 __LF                  \
+        subs    x1, x11, x0 __LF                   \
+        lsr     x16, x11, #32 __LF                 \
+        sbc     x11, x11, x16 __LF                 \
+        adds    x12, x12, x0 __LF                  \
+        adcs    x13, x13, x16 __LF                 \
+        adcs    x14, x14, x1 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        lsl     x0, x12, #32 __LF                  \
+        subs    x1, x12, x0 __LF                   \
+        lsr     x16, x12, #32 __LF                 \
+        sbc     x12, x12, x16 __LF                 \
+        adds    x13, x13, x0 __LF                  \
+        adcs    x14, x14, x16 __LF                 \
+        adcs    x11, x11, x1 __LF                  \
+        adc     x12, x12, xzr __LF                 \
+        stp     x13, x14, [P0] __LF                \
+        stp     x11, x12, [P0+16] __LF             \
+        mul     x11, x5, x9 __LF                   \
+        mul     x13, x6, x10 __LF                  \
+        umulh   x12, x5, x9 __LF                   \
+        adds    x16, x11, x13 __LF                 \
+        umulh   x14, x6, x10 __LF                  \
+        adcs    x0, x12, x14 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        adds    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        subs    x15, x5, x6 __LF                   \
+        cneg    x15, x15, lo __LF                  \
+        csetm   x1, lo __LF                        \
+        subs    x0, x10, x9 __LF                   \
+        cneg    x0, x0, lo __LF                    \
+        mul     x16, x15, x0 __LF                  \
+        umulh   x0, x15, x0 __LF                   \
+        cinv    x1, x1, lo __LF                    \
+        eor     x16, x16, x1 __LF                  \
+        eor     x0, x0, x1 __LF                    \
+        cmn     x1, #1 __LF                        \
+        adcs    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adc     x14, x14, x1 __LF                  \
+        subs    x3, x5, x3 __LF                    \
+        sbcs    x4, x6, x4 __LF                    \
+        ngc     x5, xzr __LF                       \
+        cmn     x5, #1 __LF                        \
+        eor     x3, x3, x5 __LF                    \
+        adcs    x3, x3, xzr __LF                   \
+        eor     x4, x4, x5 __LF                    \
+        adcs    x4, x4, xzr __LF                   \
+        subs    x7, x7, x9 __LF                    \
+        sbcs    x8, x8, x10 __LF                   \
+        ngc     x9, xzr __LF                       \
+        cmn     x9, #1 __LF                        \
+        eor     x7, x7, x9 __LF                    \
+        adcs    x7, x7, xzr __LF                   \
+        eor     x8, x8, x9 __LF                    \
+        adcs    x8, x8, xzr __LF                   \
+        eor     x10, x5, x9 __LF                   \
+        ldp     x15, x1, [P0] __LF                 \
+        adds    x15, x11, x15 __LF                 \
+        adcs    x1, x12, x1 __LF                   \
+        ldp     x5, x9, [P0+16] __LF               \
+        adcs    x5, x13, x5 __LF                   \
+        adcs    x9, x14, x9 __LF                   \
+        adc     x2, xzr, xzr __LF                  \
+        mul     x11, x3, x7 __LF                   \
+        mul     x13, x4, x8 __LF                   \
+        umulh   x12, x3, x7 __LF                   \
+        adds    x16, x11, x13 __LF                 \
+        umulh   x14, x4, x8 __LF                   \
+        adcs    x0, x12, x14 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        adds    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adcs    x14, x14, xzr __LF                 \
+        subs    x3, x3, x4 __LF                    \
+        cneg    x3, x3, lo __LF                    \
+        csetm   x4, lo __LF                        \
+        subs    x0, x8, x7 __LF                    \
+        cneg    x0, x0, lo __LF                    \
+        mul     x16, x3, x0 __LF                   \
+        umulh   x0, x3, x0 __LF                    \
+        cinv    x4, x4, lo __LF                    \
+        eor     x16, x16, x4 __LF                  \
+        eor     x0, x0, x4 __LF                    \
+        cmn     x4, #1 __LF                        \
+        adcs    x12, x12, x16 __LF                 \
+        adcs    x13, x13, x0 __LF                  \
+        adc     x14, x14, x4 __LF                  \
+        cmn     x10, #1 __LF                       \
+        eor     x11, x11, x10 __LF                 \
+        adcs    x11, x11, x15 __LF                 \
+        eor     x12, x12, x10 __LF                 \
+        adcs    x12, x12, x1 __LF                  \
+        eor     x13, x13, x10 __LF                 \
+        adcs    x13, x13, x5 __LF                  \
+        eor     x14, x14, x10 __LF                 \
+        adcs    x14, x14, x9 __LF                  \
+        adcs    x3, x2, x10 __LF                   \
+        adcs    x4, x10, xzr __LF                  \
+        adc     x10, x10, xzr __LF                 \
+        adds    x13, x13, x15 __LF                 \
+        adcs    x14, x14, x1 __LF                  \
+        adcs    x3, x3, x5 __LF                    \
+        adcs    x4, x4, x9 __LF                    \
+        adc     x10, x10, x2 __LF                  \
+        lsl     x0, x11, #32 __LF                  \
+        subs    x1, x11, x0 __LF                   \
+        lsr     x16, x11, #32 __LF                 \
+        sbc     x11, x11, x16 __LF                 \
+        adds    x12, x12, x0 __LF                  \
+        adcs    x13, x13, x16 __LF                 \
+        adcs    x14, x14, x1 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        lsl     x0, x12, #32 __LF                  \
+        subs    x1, x12, x0 __LF                   \
+        lsr     x16, x12, #32 __LF                 \
+        sbc     x12, x12, x16 __LF                 \
+        adds    x13, x13, x0 __LF                  \
+        adcs    x14, x14, x16 __LF                 \
+        adcs    x11, x11, x1 __LF                  \
+        adc     x12, x12, xzr __LF                 \
+        adds    x3, x3, x11 __LF                   \
+        adcs    x4, x4, x12 __LF                   \
+        adc     x10, x10, xzr __LF                 \
+        add     x2, x10, #1 __LF                   \
+        lsl     x16, x2, #32 __LF                  \
+        adds    x4, x4, x16 __LF                   \
+        adc     x10, x10, xzr __LF                 \
+        neg     x15, x2 __LF                       \
+        sub     x16, x16, #1 __LF                  \
+        subs    x13, x13, x15 __LF                 \
+        sbcs    x14, x14, x16 __LF                 \
+        sbcs    x3, x3, xzr __LF                   \
+        sbcs    x4, x4, x2 __LF                    \
+        sbcs    x7, x10, x2 __LF                   \
+        adds    x13, x13, x7 __LF                  \
+        mov     x10, #4294967295 __LF              \
+        and     x10, x10, x7 __LF                  \
+        adcs    x14, x14, x10 __LF                 \
+        adcs    x3, x3, xzr __LF                   \
+        mov     x10, #-4294967295 __LF             \
+        and     x10, x10, x7 __LF                  \
+        adc     x4, x4, x10 __LF                   \
+        stp     x13, x14, [P0] __LF                \
+        stp     x3, x4, [P0+16]
+
+// Corresponds to bignum_montsqr_p256 but uses x0 in place of x17
+
+#define montsqr_p256(P0,P1)                     \
+        ldp     x2, x3, [P1] __LF                  \
+        ldp     x4, x5, [P1+16] __LF               \
+        umull   x15, w2, w2 __LF                   \
+        lsr     x11, x2, #32 __LF                  \
+        umull   x16, w11, w11 __LF                 \
+        umull   x11, w2, w11 __LF                  \
+        adds    x15, x15, x11, lsl #33 __LF        \
+        lsr     x11, x11, #31 __LF                 \
+        adc     x16, x16, x11 __LF                 \
+        umull   x0, w3, w3 __LF                    \
+        lsr     x11, x3, #32 __LF                  \
+        umull   x1, w11, w11 __LF                  \
+        umull   x11, w3, w11 __LF                  \
+        mul     x12, x2, x3 __LF                   \
+        umulh   x13, x2, x3 __LF                   \
+        adds    x0, x0, x11, lsl #33 __LF          \
+        lsr     x11, x11, #31 __LF                 \
+        adc     x1, x1, x11 __LF                   \
+        adds    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adc     x1, x1, xzr __LF                   \
+        adds    x16, x16, x12 __LF                 \
+        adcs    x0, x0, x13 __LF                   \
+        adc     x1, x1, xzr __LF                   \
+        lsl     x12, x15, #32 __LF                 \
+        subs    x13, x15, x12 __LF                 \
+        lsr     x11, x15, #32 __LF                 \
+        sbc     x15, x15, x11 __LF                 \
+        adds    x16, x16, x12 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        adcs    x1, x1, x13 __LF                   \
+        adc     x15, x15, xzr __LF                 \
+        lsl     x12, x16, #32 __LF                 \
+        subs    x13, x16, x12 __LF                 \
+        lsr     x11, x16, #32 __LF                 \
+        sbc     x16, x16, x11 __LF                 \
+        adds    x0, x0, x12 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        adcs    x15, x15, x13 __LF                 \
+        adc     x16, x16, xzr __LF                 \
+        mul     x6, x2, x4 __LF                    \
+        mul     x14, x3, x5 __LF                   \
+        umulh   x8, x2, x4 __LF                    \
+        subs    x10, x2, x3 __LF                   \
+        cneg    x10, x10, lo __LF                  \
+        csetm   x13, lo __LF                       \
+        subs    x12, x5, x4 __LF                   \
+        cneg    x12, x12, lo __LF                  \
+        mul     x11, x10, x12 __LF                 \
+        umulh   x12, x10, x12 __LF                 \
+        cinv    x13, x13, lo __LF                  \
+        eor     x11, x11, x13 __LF                 \
+        eor     x12, x12, x13 __LF                 \
+        adds    x7, x6, x8 __LF                    \
+        adc     x8, x8, xzr __LF                   \
+        umulh   x9, x3, x5 __LF                    \
+        adds    x7, x7, x14 __LF                   \
+        adcs    x8, x8, x9 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x8, x8, x14 __LF                   \
+        adc     x9, x9, xzr __LF                   \
+        cmn     x13, #1 __LF                       \
+        adcs    x7, x7, x11 __LF                   \
+        adcs    x8, x8, x12 __LF                   \
+        adc     x9, x9, x13 __LF                   \
+        adds    x6, x6, x6 __LF                    \
+        adcs    x7, x7, x7 __LF                    \
+        adcs    x8, x8, x8 __LF                    \
+        adcs    x9, x9, x9 __LF                    \
+        adc     x10, xzr, xzr __LF                 \
+        adds    x6, x6, x0 __LF                    \
+        adcs    x7, x7, x1 __LF                    \
+        adcs    x8, x8, x15 __LF                   \
+        adcs    x9, x9, x16 __LF                   \
+        adc     x10, x10, xzr __LF                 \
+        lsl     x12, x6, #32 __LF                  \
+        subs    x13, x6, x12 __LF                  \
+        lsr     x11, x6, #32 __LF                  \
+        sbc     x6, x6, x11 __LF                   \
+        adds    x7, x7, x12 __LF                   \
+        adcs    x8, x8, x11 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x6 __LF                  \
+        adc     x6, xzr, xzr __LF                  \
+        lsl     x12, x7, #32 __LF                  \
+        subs    x13, x7, x12 __LF                  \
+        lsr     x11, x7, #32 __LF                  \
+        sbc     x7, x7, x11 __LF                   \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x11 __LF                   \
+        adcs    x10, x10, x13 __LF                 \
+        adcs    x6, x6, x7 __LF                    \
+        adc     x7, xzr, xzr __LF                  \
+        mul     x11, x4, x4 __LF                   \
+        adds    x8, x8, x11 __LF                   \
+        mul     x12, x5, x5 __LF                   \
+        umulh   x11, x4, x4 __LF                   \
+        adcs    x9, x9, x11 __LF                   \
+        adcs    x10, x10, x12 __LF                 \
+        umulh   x12, x5, x5 __LF                   \
+        adcs    x6, x6, x12 __LF                   \
+        adc     x7, x7, xzr __LF                   \
+        mul     x11, x4, x5 __LF                   \
+        umulh   x12, x4, x5 __LF                   \
+        adds    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adc     x13, xzr, xzr __LF                 \
+        adds    x9, x9, x11 __LF                   \
+        adcs    x10, x10, x12 __LF                 \
+        adcs    x6, x6, x13 __LF                   \
+        adcs    x7, x7, xzr __LF                   \
+        mov     x11, #4294967295 __LF              \
+        adds    x5, x8, #1 __LF                    \
+        sbcs    x11, x9, x11 __LF                  \
+        mov     x13, #-4294967295 __LF             \
+        sbcs    x12, x10, xzr __LF                 \
+        sbcs    x13, x6, x13 __LF                  \
+        sbcs    xzr, x7, xzr __LF                  \
+        csel    x8, x5, x8, hs __LF                \
+        csel    x9, x11, x9, hs __LF               \
+        csel    x10, x12, x10, hs __LF             \
+        csel    x6, x13, x6, hs __LF               \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x6, [P0+16]
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        csetm   x3, cc __LF                        \
+        adds    x5, x5, x3 __LF                    \
+        mov     x4, #0xffffffff __LF               \
+        and     x4, x4, x3 __LF                    \
+        adcs    x6, x6, x4 __LF                    \
+        adcs    x7, x7, xzr __LF                   \
+        mov     x4, #0xffffffff00000001 __LF       \
+        and     x4, x4, x3 __LF                    \
+        adc     x8, x8, x4 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+S2N_BN_SYMBOL(p256_montjmixadd):
+        CFI_START
+
+// Save regs and make room on stack for temporary variables
+
+        CFI_PUSH2(x19,x20)
+        CFI_DEC_SP(NSPACE)
+
+// Move the input arguments to stable places
+
+        mov     input_z, x0
+        mov     input_x, x1
+        mov     input_y, x2
+
+// Main code, just a sequence of basic field operations
+// 8 * multiply + 3 * square + 7 * subtract
+
+        montsqr_p256(zp2,z_1)
+        montmul_p256(y2a,z_1,y_2)
+
+        montmul_p256(x2a,zp2,x_2)
+        montmul_p256(y2a,zp2,y2a)
+
+        sub_p256(xd,x2a,x_1)
+        sub_p256(yd,y2a,y_1)
+
+        montsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x_1)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(resz,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y_1)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Test if z_1 = 0 to decide if p1 = 0 (up to projective equivalence)
+
+        ldp     x0, x1, [z_1]
+        ldp     x2, x3, [z_1+16]
+        orr     x4, x0, x1
+        orr     x5, x2, x3
+        orr     x4, x4, x5
+        cmp     x4, xzr
+
+// Multiplex: if p1 <> 0 just copy the computed result from the staging area.
+// If p1 = 0 then return the point p2 augmented with a z = 1 coordinate (in
+// Montgomery form so not the simple constant 1 but rather 2^256 - p_256),
+// hence giving 0 + p2 = p2 for the final result.
+
+        ldp     x0, x1, [resx]
+        ldp     x12, x13, [x_2]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x2, x3, [resx+16]
+        ldp     x12, x13, [x_2+16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+
+        ldp     x4, x5, [resy]
+        ldp     x12, x13, [y_2]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x6, x7, [resy+16]
+        ldp     x12, x13, [y_2+16]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+
+        ldp     x8, x9, [resz]
+        mov     x12, #0x0000000000000001
+        mov     x13, #0xffffffff00000000
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x10, x11, [resz+16]
+        mov     x12, #0xffffffffffffffff
+        mov     x13, #0x00000000fffffffe
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+
+        stp     x0, x1, [x_3]
+        stp     x2, x3, [x_3+16]
+        stp     x4, x5, [y_3]
+        stp     x6, x7, [y_3+16]
+        stp     x8, x9, [z_3]
+        stp     x10, x11, [z_3+16]
+
+// Restore registers and return
+
+        CFI_INC_SP(NSPACE)
+        CFI_POP2(x19,x20)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjmixadd)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/arm/p256_montjmixadd_alt.S b/cbits/s2n/arm/p256_montjmixadd_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/arm/p256_montjmixadd_alt.S
@@ -0,0 +1,517 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjmixadd_alt(uint64_t p3[static 12],
+//                                     const uint64_t p1[static 12],
+//                                     const uint64_t p2[static 8]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+// The "mixed" part means that p2 only has x and y coordinates, with the
+// implicit z coordinate assumed to be the identity.
+//
+// Standard ARM ABI: X0 = p3, X1 = p1, X2 = p2
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_arm.h"
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjmixadd_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjmixadd_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjmixadd_alt)
+
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Stable homes for input arguments during main code sequence
+
+#define input_z x15
+#define input_x x16
+#define input_y x17
+
+// Pointer-offset pairs for inputs and outputs
+
+#define x_1 input_x, #0
+#define y_1 input_x, #NUMSIZE
+#define z_1 input_x, #(2*NUMSIZE)
+
+#define x_2 input_y, #0
+#define y_2 input_y, #NUMSIZE
+
+#define x_3 input_z, #0
+#define y_3 input_z, #NUMSIZE
+#define z_3 input_z, #(2*NUMSIZE)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// #NSPACE is the total stack needed for these temporaries
+
+#define zp2 sp, #(NUMSIZE*0)
+#define ww sp, #(NUMSIZE*0)
+#define resx sp, #(NUMSIZE*0)
+
+#define yd sp, #(NUMSIZE*1)
+#define y2a sp, #(NUMSIZE*1)
+
+#define x2a sp, #(NUMSIZE*2)
+#define zzx2 sp, #(NUMSIZE*2)
+
+#define zz sp, #(NUMSIZE*3)
+#define t1 sp, #(NUMSIZE*3)
+
+#define t2 sp, #(NUMSIZE*4)
+#define zzx1 sp, #(NUMSIZE*4)
+#define resy sp, #(NUMSIZE*4)
+
+#define xd sp, #(NUMSIZE*5)
+#define resz sp, #(NUMSIZE*5)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds to bignum_montmul_p256_alt except registers
+
+#define montmul_p256(P0,P1,P2)                  \
+        ldp     x3, x4, [P1] __LF                  \
+        ldp     x7, x8, [P2] __LF                  \
+        mul     x12, x3, x7 __LF                   \
+        umulh   x13, x3, x7 __LF                   \
+        mul     x11, x3, x8 __LF                   \
+        umulh   x14, x3, x8 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        ldp     x9, x10, [P2+16] __LF              \
+        mul     x11, x3, x9 __LF                   \
+        umulh   x0, x3, x9 __LF                    \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x3, x10 __LF                  \
+        umulh   x1, x3, x10 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x1, x1, xzr __LF                   \
+        ldp     x5, x6, [P1+16] __LF               \
+        mul     x11, x4, x7 __LF                   \
+        adds    x13, x13, x11 __LF                 \
+        mul     x11, x4, x8 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x4, x9 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x4, x10 __LF                  \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x3, x4, x10 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        umulh   x11, x4, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        umulh   x11, x4, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        umulh   x11, x4, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        adc     x3, x3, xzr __LF                   \
+        mul     x11, x5, x7 __LF                   \
+        adds    x14, x14, x11 __LF                 \
+        mul     x11, x5, x8 __LF                   \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x5, x9 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x5, x10 __LF                  \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x4, x5, x10 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        umulh   x11, x5, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        umulh   x11, x5, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        umulh   x11, x5, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        adc     x4, x4, xzr __LF                   \
+        mul     x11, x6, x7 __LF                   \
+        adds    x0, x0, x11 __LF                   \
+        mul     x11, x6, x8 __LF                   \
+        adcs    x1, x1, x11 __LF                   \
+        mul     x11, x6, x9 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        mul     x11, x6, x10 __LF                  \
+        adcs    x4, x4, x11 __LF                   \
+        umulh   x5, x6, x10 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        mov     x10, #0xffffffff00000001 __LF      \
+        adds    x13, x13, x12, lsl #32 __LF        \
+        lsr     x11, x12, #32 __LF                 \
+        adcs    x14, x14, x11 __LF                 \
+        mul     x11, x12, x10 __LF                 \
+        umulh   x12, x12, x10 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        adc     x12, x12, xzr __LF                 \
+        umulh   x11, x6, x7 __LF                   \
+        adds    x1, x1, x11 __LF                   \
+        umulh   x11, x6, x8 __LF                   \
+        adcs    x3, x3, x11 __LF                   \
+        umulh   x11, x6, x9 __LF                   \
+        adcs    x4, x4, x11 __LF                   \
+        adc     x5, x5, xzr __LF                   \
+        adds    x14, x14, x13, lsl #32 __LF        \
+        lsr     x11, x13, #32 __LF                 \
+        adcs    x0, x0, x11 __LF                   \
+        mul     x11, x13, x10 __LF                 \
+        umulh   x13, x13, x10 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        adc     x13, x13, xzr __LF                 \
+        adds    x0, x0, x14, lsl #32 __LF          \
+        lsr     x11, x14, #32 __LF                 \
+        adcs    x12, x12, x11 __LF                 \
+        mul     x11, x14, x10 __LF                 \
+        umulh   x14, x14, x10 __LF                 \
+        adcs    x13, x13, x11 __LF                 \
+        adc     x14, x14, xzr __LF                 \
+        adds    x12, x12, x0, lsl #32 __LF         \
+        lsr     x11, x0, #32 __LF                  \
+        adcs    x13, x13, x11 __LF                 \
+        mul     x11, x0, x10 __LF                  \
+        umulh   x0, x0, x10 __LF                   \
+        adcs    x14, x14, x11 __LF                 \
+        adc     x0, x0, xzr __LF                   \
+        adds    x12, x12, x1 __LF                  \
+        adcs    x13, x13, x3 __LF                  \
+        adcs    x14, x14, x4 __LF                  \
+        adcs    x0, x0, x5 __LF                    \
+        cset    x8, cs __LF                        \
+        mov     x11, #0xffffffff __LF              \
+        adds    x1, x12, #0x1 __LF                 \
+        sbcs    x3, x13, x11 __LF                  \
+        sbcs    x4, x14, xzr __LF                  \
+        sbcs    x5, x0, x10 __LF                   \
+        sbcs    xzr, x8, xzr __LF                  \
+        csel    x12, x12, x1, cc __LF              \
+        csel    x13, x13, x3, cc __LF              \
+        csel    x14, x14, x4, cc __LF              \
+        csel    x0, x0, x5, cc __LF                \
+        stp     x12, x13, [P0] __LF                \
+        stp     x14, x0, [P0+16]
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        ldp     x2, x3, [P1] __LF                  \
+        mul     x9, x2, x3 __LF                    \
+        umulh   x10, x2, x3 __LF                   \
+        ldp     x4, x5, [P1+16] __LF               \
+        mul     x11, x2, x5 __LF                   \
+        umulh   x12, x2, x5 __LF                   \
+        mul     x6, x2, x4 __LF                    \
+        umulh   x7, x2, x4 __LF                    \
+        adds    x10, x10, x6 __LF                  \
+        adcs    x11, x11, x7 __LF                  \
+        mul     x6, x3, x4 __LF                    \
+        umulh   x7, x3, x4 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x11, x11, x6 __LF                  \
+        mul     x13, x4, x5 __LF                   \
+        umulh   x14, x4, x5 __LF                   \
+        adcs    x12, x12, x7 __LF                  \
+        mul     x6, x3, x5 __LF                    \
+        umulh   x7, x3, x5 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x12, x12, x6 __LF                  \
+        adcs    x13, x13, x7 __LF                  \
+        adc     x14, x14, xzr __LF                 \
+        adds    x9, x9, x9 __LF                    \
+        adcs    x10, x10, x10 __LF                 \
+        adcs    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adcs    x14, x14, x14 __LF                 \
+        cset    x7, cs __LF                        \
+        umulh   x6, x2, x2 __LF                    \
+        mul     x8, x2, x2 __LF                    \
+        adds    x9, x9, x6 __LF                    \
+        mul     x6, x3, x3 __LF                    \
+        adcs    x10, x10, x6 __LF                  \
+        umulh   x6, x3, x3 __LF                    \
+        adcs    x11, x11, x6 __LF                  \
+        mul     x6, x4, x4 __LF                    \
+        adcs    x12, x12, x6 __LF                  \
+        umulh   x6, x4, x4 __LF                    \
+        adcs    x13, x13, x6 __LF                  \
+        mul     x6, x5, x5 __LF                    \
+        adcs    x14, x14, x6 __LF                  \
+        umulh   x6, x5, x5 __LF                    \
+        adc     x7, x7, x6 __LF                    \
+        adds    x9, x9, x8, lsl #32 __LF           \
+        lsr     x3, x8, #32 __LF                   \
+        adcs    x10, x10, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x8, x3 __LF                    \
+        umulh   x8, x8, x3 __LF                    \
+        adcs    x11, x11, x2 __LF                  \
+        adc     x8, x8, xzr __LF                   \
+        adds    x10, x10, x9, lsl #32 __LF         \
+        lsr     x3, x9, #32 __LF                   \
+        adcs    x11, x11, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x9, x3 __LF                    \
+        umulh   x9, x9, x3 __LF                    \
+        adcs    x8, x8, x2 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x11, x11, x10, lsl #32 __LF        \
+        lsr     x3, x10, #32 __LF                  \
+        adcs    x8, x8, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x10, x3 __LF                   \
+        umulh   x10, x10, x3 __LF                  \
+        adcs    x9, x9, x2 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        adds    x8, x8, x11, lsl #32 __LF          \
+        lsr     x3, x11, #32 __LF                  \
+        adcs    x9, x9, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x11, x3 __LF                   \
+        umulh   x11, x11, x3 __LF                  \
+        adcs    x10, x10, x2 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x14 __LF                 \
+        adcs    x11, x11, x7 __LF                  \
+        cset    x2, cs __LF                        \
+        mov     x3, #0xffffffff __LF               \
+        mov     x5, #0xffffffff00000001 __LF       \
+        adds    x12, x8, #0x1 __LF                 \
+        sbcs    x13, x9, x3 __LF                   \
+        sbcs    x14, x10, xzr __LF                 \
+        sbcs    x7, x11, x5 __LF                   \
+        sbcs    xzr, x2, xzr __LF                  \
+        csel    x8, x8, x12, cc __LF               \
+        csel    x9, x9, x13, cc __LF               \
+        csel    x10, x10, x14, cc __LF             \
+        csel    x11, x11, x7, cc __LF              \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x11, [P0+16]
+
+// Almost-Montgomery variant which we use when an input to other muls
+// with the other argument fully reduced (which is always safe).
+
+#define amontsqr_p256(P0,P1)                    \
+        ldp     x2, x3, [P1] __LF                  \
+        mul     x9, x2, x3 __LF                    \
+        umulh   x10, x2, x3 __LF                   \
+        ldp     x4, x5, [P1+16] __LF               \
+        mul     x11, x2, x5 __LF                   \
+        umulh   x12, x2, x5 __LF                   \
+        mul     x6, x2, x4 __LF                    \
+        umulh   x7, x2, x4 __LF                    \
+        adds    x10, x10, x6 __LF                  \
+        adcs    x11, x11, x7 __LF                  \
+        mul     x6, x3, x4 __LF                    \
+        umulh   x7, x3, x4 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x11, x11, x6 __LF                  \
+        mul     x13, x4, x5 __LF                   \
+        umulh   x14, x4, x5 __LF                   \
+        adcs    x12, x12, x7 __LF                  \
+        mul     x6, x3, x5 __LF                    \
+        umulh   x7, x3, x5 __LF                    \
+        adc     x7, x7, xzr __LF                   \
+        adds    x12, x12, x6 __LF                  \
+        adcs    x13, x13, x7 __LF                  \
+        adc     x14, x14, xzr __LF                 \
+        adds    x9, x9, x9 __LF                    \
+        adcs    x10, x10, x10 __LF                 \
+        adcs    x11, x11, x11 __LF                 \
+        adcs    x12, x12, x12 __LF                 \
+        adcs    x13, x13, x13 __LF                 \
+        adcs    x14, x14, x14 __LF                 \
+        cset    x7, cs __LF                        \
+        umulh   x6, x2, x2 __LF                    \
+        mul     x8, x2, x2 __LF                    \
+        adds    x9, x9, x6 __LF                    \
+        mul     x6, x3, x3 __LF                    \
+        adcs    x10, x10, x6 __LF                  \
+        umulh   x6, x3, x3 __LF                    \
+        adcs    x11, x11, x6 __LF                  \
+        mul     x6, x4, x4 __LF                    \
+        adcs    x12, x12, x6 __LF                  \
+        umulh   x6, x4, x4 __LF                    \
+        adcs    x13, x13, x6 __LF                  \
+        mul     x6, x5, x5 __LF                    \
+        adcs    x14, x14, x6 __LF                  \
+        umulh   x6, x5, x5 __LF                    \
+        adc     x7, x7, x6 __LF                    \
+        adds    x9, x9, x8, lsl #32 __LF           \
+        lsr     x3, x8, #32 __LF                   \
+        adcs    x10, x10, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x8, x3 __LF                    \
+        umulh   x8, x8, x3 __LF                    \
+        adcs    x11, x11, x2 __LF                  \
+        adc     x8, x8, xzr __LF                   \
+        adds    x10, x10, x9, lsl #32 __LF         \
+        lsr     x3, x9, #32 __LF                   \
+        adcs    x11, x11, x3 __LF                  \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x9, x3 __LF                    \
+        umulh   x9, x9, x3 __LF                    \
+        adcs    x8, x8, x2 __LF                    \
+        adc     x9, x9, xzr __LF                   \
+        adds    x11, x11, x10, lsl #32 __LF        \
+        lsr     x3, x10, #32 __LF                  \
+        adcs    x8, x8, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x10, x3 __LF                   \
+        umulh   x10, x10, x3 __LF                  \
+        adcs    x9, x9, x2 __LF                    \
+        adc     x10, x10, xzr __LF                 \
+        adds    x8, x8, x11, lsl #32 __LF          \
+        lsr     x3, x11, #32 __LF                  \
+        adcs    x9, x9, x3 __LF                    \
+        mov     x3, #0xffffffff00000001 __LF       \
+        mul     x2, x11, x3 __LF                   \
+        umulh   x11, x11, x3 __LF                  \
+        adcs    x10, x10, x2 __LF                  \
+        adc     x11, x11, xzr __LF                 \
+        adds    x8, x8, x12 __LF                   \
+        adcs    x9, x9, x13 __LF                   \
+        adcs    x10, x10, x14 __LF                 \
+        adcs    x11, x11, x7 __LF                  \
+        mov     x2, #0xffffffffffffffff __LF       \
+        csel    x2, xzr, x2, cc __LF               \
+        mov     x3, #0xffffffff __LF               \
+        csel    x3, xzr, x3, cc __LF               \
+        mov     x5, #0xffffffff00000001 __LF       \
+        csel    x5, xzr, x5, cc __LF               \
+        subs    x8, x8, x2 __LF                    \
+        sbcs    x9, x9, x3 __LF                    \
+        sbcs    x10, x10, xzr __LF                 \
+        sbc     x11, x11, x5 __LF                  \
+        stp     x8, x9, [P0] __LF                  \
+        stp     x10, x11, [P0+16]
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        ldp     x5, x6, [P1] __LF                  \
+        ldp     x4, x3, [P2] __LF                  \
+        subs    x5, x5, x4 __LF                    \
+        sbcs    x6, x6, x3 __LF                    \
+        ldp     x7, x8, [P1+16] __LF               \
+        ldp     x4, x3, [P2+16] __LF               \
+        sbcs    x7, x7, x4 __LF                    \
+        sbcs    x8, x8, x3 __LF                    \
+        csetm   x3, cc __LF                        \
+        adds    x5, x5, x3 __LF                    \
+        mov     x4, #0xffffffff __LF               \
+        and     x4, x4, x3 __LF                    \
+        adcs    x6, x6, x4 __LF                    \
+        adcs    x7, x7, xzr __LF                   \
+        mov     x4, #0xffffffff00000001 __LF       \
+        and     x4, x4, x3 __LF                    \
+        adc     x8, x8, x4 __LF                    \
+        stp     x5, x6, [P0] __LF                  \
+        stp     x7, x8, [P0+16]
+
+S2N_BN_SYMBOL(p256_montjmixadd_alt):
+        CFI_START
+
+// Make room on stack for temporary variables
+// Move the input arguments to stable places
+
+        CFI_DEC_SP(NSPACE)
+
+        mov     input_z, x0
+        mov     input_x, x1
+        mov     input_y, x2
+
+// Main code, just a sequence of basic field operations
+// 8 * multiply + 3 * square + 7 * subtract
+
+        amontsqr_p256(zp2,z_1)
+        montmul_p256(y2a,z_1,y_2)
+
+        montmul_p256(x2a,zp2,x_2)
+        montmul_p256(y2a,zp2,y2a)
+
+        sub_p256(xd,x2a,x_1)
+        sub_p256(yd,y2a,y_1)
+
+        amontsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x_1)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(resz,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y_1)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Test if z_1 = 0 to decide if p1 = 0 (up to projective equivalence)
+
+        ldp     x0, x1, [z_1]
+        ldp     x2, x3, [z_1+16]
+        orr     x4, x0, x1
+        orr     x5, x2, x3
+        orr     x4, x4, x5
+        cmp     x4, xzr
+
+// Multiplex: if p1 <> 0 just copy the computed result from the staging area.
+// If p1 = 0 then return the point p2 augmented with a z = 1 coordinate (in
+// Montgomery form so not the simple constant 1 but rather 2^256 - p_256),
+// hence giving 0 + p2 = p2 for the final result.
+
+        ldp     x0, x1, [resx]
+        ldp     x12, x13, [x_2]
+        csel    x0, x0, x12, ne
+        csel    x1, x1, x13, ne
+        ldp     x2, x3, [resx+16]
+        ldp     x12, x13, [x_2+16]
+        csel    x2, x2, x12, ne
+        csel    x3, x3, x13, ne
+
+        ldp     x4, x5, [resy]
+        ldp     x12, x13, [y_2]
+        csel    x4, x4, x12, ne
+        csel    x5, x5, x13, ne
+        ldp     x6, x7, [resy+16]
+        ldp     x12, x13, [y_2+16]
+        csel    x6, x6, x12, ne
+        csel    x7, x7, x13, ne
+
+        ldp     x8, x9, [resz]
+        mov     x12, #0x0000000000000001
+        mov     x13, #0xffffffff00000000
+        csel    x8, x8, x12, ne
+        csel    x9, x9, x13, ne
+        ldp     x10, x11, [resz+16]
+        mov     x12, #0xffffffffffffffff
+        mov     x13, #0x00000000fffffffe
+        csel    x10, x10, x12, ne
+        csel    x11, x11, x13, ne
+
+        stp     x0, x1, [x_3]
+        stp     x2, x3, [x_3+16]
+        stp     x4, x5, [y_3]
+        stp     x6, x7, [y_3+16]
+        stp     x8, x9, [z_3]
+        stp     x10, x11, [z_3+16]
+
+// Restore stack and return
+
+        CFI_INC_SP(NSPACE)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjmixadd_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/import.sh b/cbits/s2n/import.sh
--- a/cbits/s2n/import.sh
+++ b/cbits/s2n/import.sh
@@ -56,6 +56,16 @@
 take p256 p256_scalarmul
 take p256 p256_scalarmulbase
 
+# The Jacobian point operations, which ECDSA verification walks itself: it
+# multiplies two scalars at once, in variable time, which is allowed there
+# because everything it touches is public.  See cbits/p256/p256_verify.c.
+take p256 p256_montjadd
+take p256 p256_montjdouble
+take p256 p256_montjmixadd
+take p256 bignum_tomont_p256
+take p256 bignum_demont_p256
+take p256 bignum_neg_p256
+
 # P-384 and P-521 have no affine wrapper upstream, so the Montgomery and
 # Jacobian conversions are built here out of these; the glue is in
 # cbits/crypton_ecc_s2n.c.
@@ -77,6 +87,12 @@
 # there is one code path.
 take curve25519 curve25519_x25519
 take curve25519 curve25519_x25519base
+
+# Ed25519's base point multiplication, which signing does twice -- once for
+# the nonce's point and once for the public key it derives from the secret
+# key every time -- and the encoding of the result, which has one form.
+take curve25519 edwards25519_scalarmulbase
+take curve25519 edwards25519_encode
 
 # Inversion modulo an odd number of any size, which is what ECDSA does once
 # per signature and once per verification.  It uses no instruction beyond
diff --git a/cbits/s2n/x86_att/bignum_demont_p256.S b/cbits/s2n/x86_att/bignum_demont_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/bignum_demont_p256.S
@@ -0,0 +1,116 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced
+// Input x[4]; output z[4]
+//
+//    extern void bignum_demont_p256(uint64_t z[static 4],
+//                                   const uint64_t x[static 4]);
+//
+// This assumes the input is < p_256 for correctness. If this is not the case,
+// use the variant "bignum_deamont_p256" instead.
+//
+// Standard x86-64 ABI: RDI = z, RSI = x
+// Microsoft x64 ABI:   RCX = z, RDX = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_demont_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_demont_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_demont_p256)
+        .text
+
+#define z %rdi
+#define x %rsi
+
+// Add %rdx * m into a register-pair (high,low)
+// maintaining consistent double-carrying with adcx and adox,
+// using %rax and %rcx as temporaries
+
+#define mulpadd(high,low,m)             \
+        mulxq   m, %rax, %rcx ;            \
+        adcxq   %rax, low ;               \
+        adoxq   %rcx, high
+
+S2N_BN_SYMBOL(bignum_demont_p256):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Save one more register to play with
+
+        CFI_PUSH(%rbx)
+
+// Set up an initial 4-word window [%r11,%r10,%r9,%r8] = x
+
+        movq    (x), %r8
+        movq    8(x), %r9
+        movq    16(x), %r10
+        movq    24(x), %r11
+
+// Fill in two zeros to the left
+
+        xorq    %rbx, %rbx
+        xorq    %rsi, %rsi
+
+// Montgomery reduce windows 0 and 1 together
+
+        movq    $0x0000000100000000, %rdx
+        mulpadd(%r10,%r9,%r8)
+        mulpadd(%r11,%r10,%r9)
+        movq    $0xffffffff00000001, %rdx
+        mulpadd(%rbx,%r11,%r8)
+        mulpadd(%rsi,%rbx,%r9)
+        movl    $0, %r8d
+        adcxq   %r8, %rsi
+
+// Append just one more leading zero (by the above %r8 = 0 already).
+
+        xorq    %r9, %r9
+
+// Montgomery reduce windows 2 and 3 together
+
+        movq    $0x0000000100000000, %rdx
+        mulpadd(%rbx,%r11,%r10)
+        mulpadd(%rsi,%rbx,%r11)
+        movq    $0xffffffff00000001, %rdx
+        mulpadd(%r8,%rsi,%r10)
+        mulpadd(%r9,%r8,%r11)
+        movl    $0, %r10d
+        adcxq   %r10, %r9
+
+// Since the input was assumed reduced modulo, i.e. < p, we actually know that
+// 2^256 * [carries; %r9;%r8;%rsi;%rbx] is <= (p - 1) + (2^256 - 1) p
+// and hence [carries; %r9;%r8;%rsi;%rbx] < p. This means in fact carries = 0
+// and [%r9;%r8;%rsi;%rbx] is already our answer, without further correction.
+// Write that back.
+
+        movq    %rbx, (z)
+        movq    %rsi, 8(z)
+        movq    %r8, 16(z)
+        movq    %r9, 24(z)
+
+// Restore saved register and return
+
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_demont_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/bignum_demont_p256_alt.S b/cbits/s2n/x86_att/bignum_demont_p256_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/bignum_demont_p256_alt.S
@@ -0,0 +1,134 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced
+// Input x[4]; output z[4]
+//
+//    extern void bignum_demont_p256_alt(uint64_t z[static 4],
+//                                       const uint64_t x[static 4]);
+//
+// This assumes the input is < p_256 for correctness. If this is not the case,
+// use the variant "bignum_deamont_p256" instead.
+//
+// Standard x86-64 ABI: RDI = z, RSI = x
+// Microsoft x64 ABI:   RCX = z, RDX = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_demont_p256_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_demont_p256_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_demont_p256_alt)
+        .text
+
+#define z %rdi
+#define x %rsi
+
+// Add %rdx * m into a register-pair (high,low)
+// maintaining consistent double-carrying with adcx and adox,
+// using %rax and %rcx as temporaries
+
+#define mulpado(high,low,m)             \
+        mulxq   m, %rax, %rcx ;            \
+        adcxq   %rax, low ;               \
+        adoxq   %rcx, high
+
+// Add %rcx * m into a register-pair (high,low) maintaining consistent
+// carry-catching with carry (negated, as bitmask) and using %rax and %rdx
+// as temporaries
+
+#define mulpadd(carry,high,low,m)       \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        subq    carry, %rdx ;             \
+        addq    %rax, low ;               \
+        adcq    %rdx, high ;              \
+        sbbq    carry, carry
+
+// Initial version assuming no carry-in
+
+#define mulpadi(carry,high,low,m)       \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        addq    %rax, low ;               \
+        adcq    %rdx, high ;              \
+        sbbq    carry, carry
+
+// Version with no carry in or out
+
+#define mulpadn(high,low,m)             \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        addq    %rax, low ;               \
+        adcq    %rdx, high
+
+S2N_BN_SYMBOL(bignum_demont_p256_alt):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Set up an initial 4-word window [%r11,%r10,%r9,%r8] = x
+
+        movq    (x), %r8
+        movq    8(x), %r9
+        movq    16(x), %r10
+        movq    24(x), %r11
+
+// Load constant 2^32; %rcx toggles between this and (1 - %rcx) below
+
+        movq    $0x0000000100000000, %rcx
+
+// Montgomery reduce windows 0 and 1 together as [%r8;%rsi;%r11;%r10]
+
+        mulpadi(%rsi,%r10,%r9,%r8)
+        mulpadd(%rsi,%r11,%r10,%r9)
+        negq    %rcx
+        negq    %rsi
+        incq    %rcx
+        mulpadi(%r8,%rsi,%r11,%r8)
+        negq    %r8
+        mulpadn(%r8,%rsi,%r9)
+
+// Montgomery reduce windows 2 and 3 together as [%r10;%r9;%r8;%rsi]
+
+        negq    %rcx
+        incq    %rcx
+        mulpadi(%r9,%rsi,%r11,%r10)
+        mulpadd(%r9,%r8,%rsi,%r11)
+        negq    %rcx
+        negq    %r9
+        incq    %rcx
+        mulpadi(%r10,%r9,%r8,%r10)
+        negq    %r10
+        mulpadn(%r10,%r9,%r11)
+
+// Since the input was assumed reduced modulo, i.e. < p, we actually know that
+// 2^256 * [carries; %r10;%r9;%r8;%rsi] is <= (p - 1) + (2^256 - 1) p
+// and hence [carries; %r10;%r9;%r8;%rsi] < p. This means in fact carries = 0
+// and [%r10;%r9;%r8;%rsi] is already our answer, without further correction.
+// Write that back.
+
+        movq    %rsi, (z)
+        movq    %r8, 8(z)
+        movq    %r9, 16(z)
+        movq    %r10, 24(z)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_demont_p256_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/bignum_neg_p256.S b/cbits/s2n/x86_att/bignum_neg_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/bignum_neg_p256.S
@@ -0,0 +1,97 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced
+// Input x[4]; output z[4]
+//
+//    extern void bignum_neg_p256(uint64_t z[static 4], const uint64_t x[static 4]);
+//
+// Standard x86-64 ABI: RDI = z, RSI = x
+// Microsoft x64 ABI:   RCX = z, RDX = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_neg_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_neg_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_neg_p256)
+        .text
+
+#define z %rdi
+#define x %rsi
+
+#define q %rdx
+
+#define d0 %rax
+#define d1 %rcx
+#define d2 %r8
+#define d3 %r9
+
+#define n1 %r10
+#define n3 %r11
+
+#define d0short %eax
+#define n1short %r10d
+
+S2N_BN_SYMBOL(bignum_neg_p256):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Load the input digits as [d3;d2;d1;d0] and also set a bitmask q
+// for the input being nonzero, so that we avoid doing -0 = p_256
+// and hence maintain strict modular reduction
+
+        movq    (x), d0
+        movq    8(x), d1
+        movq    d0, n1
+        orq     d1, n1
+        movq    16(x), d2
+        movq    24(x), d3
+        movq    d2, n3
+        orq     d3, n3
+        orq     n1, n3
+        negq    n3
+        sbbq    q, q
+
+// Load the non-trivial words of p_256 = [n3;0;n1;-1] and mask them with q
+
+        movl    $0x00000000ffffffff, n1short
+        movq    $0xffffffff00000001, n3
+        andq    q, n1
+        andq    q, n3
+
+// Do the subtraction, getting it as [n3;d0;n1;q] to avoid moves
+
+        subq    d0, q
+        movl    $0, d0short
+        sbbq    d1, n1
+        sbbq    d2, d0
+        sbbq    d3, n3
+
+// Write back
+
+        movq    q, (z)
+        movq    n1, 8(z)
+        movq    d0, 16(z)
+        movq    n3, 24(z)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_neg_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/bignum_tomont_p256.S b/cbits/s2n/x86_att/bignum_tomont_p256.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/bignum_tomont_p256.S
@@ -0,0 +1,195 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert to Montgomery form z := (2^256 * x) mod p_256
+// Input x[4]; output z[4]
+//
+//    extern void bignum_tomont_p256(uint64_t z[static 4],
+//                                   const uint64_t x[static 4]);
+//
+// Standard x86-64 ABI: RDI = z, RSI = x
+// Microsoft x64 ABI:   RCX = z, RDX = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_tomont_p256)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_tomont_p256)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_tomont_p256)
+        .text
+
+#define z %rdi
+#define x %rsi
+
+// Some temp registers for the last correction stage
+
+#define d %rax
+#define u %rdx
+#define v %rcx
+
+#define dshort %eax
+#define ushort %edx
+
+// Add %rdx * m into a register-pair (high,low)
+// maintaining consistent double-carrying with adcx and adox,
+// using %rax and %rbx as temporaries
+
+#define mulpadd(high,low,m)             \
+        mulxq   m, %rax, %rcx ;            \
+        adcxq   %rax, low ;               \
+        adoxq   %rcx, high
+
+S2N_BN_SYMBOL(bignum_tomont_p256):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// We are essentially just doing a Montgomery multiplication of x and the
+// precomputed constant y = 2^512 mod p, so the code is almost the same
+// modulo a few registers and the change from loading y[i] to using constants.
+// Because there is no y pointer to keep, we use one register less.
+
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+// Do row 0 computation, which is a bit different:
+// set up initial window [%r12,%r11,%r10,%r9,%r8] = y[0] * x
+// Unlike later, we only need a single carry chain
+
+        xorq    %r13, %r13
+        movl    $0x0000000000000003, %edx
+        mulxq   (x), %r8, %r9
+        mulxq   8(x), %rcx, %r10
+        adcxq   %rcx, %r9
+        mulxq   16(x), %rcx, %r11
+        adcxq   %rcx, %r10
+        mulxq   24(x), %rcx, %r12
+        adcxq   %rcx, %r11
+        adcxq   %r13, %r12
+
+// Add row 1
+
+        movq    $0xfffffffbffffffff, %rdx
+        xorq    %r14, %r14
+        mulpadd(%r10,%r9,(x))
+        mulpadd(%r11,%r10,8(x))
+        mulpadd(%r12,%r11,16(x))
+        mulpadd(%r13,%r12,24(x))
+        adcq   %r14, %r13
+
+// Montgomery reduce windows 0 and 1 together
+
+        xorq    %r15, %r15
+        movq    $0x0000000100000000, %rdx
+        mulpadd(%r10,%r9,%r8)
+        mulpadd(%r11,%r10,%r9)
+        movq    $0xffffffff00000001, %rdx
+        mulpadd(%r12,%r11,%r8)
+        mulpadd(%r13,%r12,%r9)
+        adcxq   %r15, %r13
+        adoxq   %r15, %r14
+        adcxq   %r15, %r14
+
+// Add row 2
+
+        movq    $0xfffffffffffffffe, %rdx
+        xorq    %r8, %r8
+        mulpadd(%r11,%r10,(x))
+        mulpadd(%r12,%r11,8(x))
+        mulpadd(%r13,%r12,16(x))
+        mulpadd(%r14,%r13,24(x))
+        adcxq   %r8, %r14
+        adoxq   %r8, %r15
+        adcxq   %r8, %r15
+
+// Add row 3
+
+        movq    $0x00000004fffffffd, %rdx
+        xorq    %r9, %r9
+        mulpadd(%r12,%r11,(x))
+        mulpadd(%r13,%r12,8(x))
+        mulpadd(%r14,%r13,16(x))
+        mulpadd(%r15,%r14,24(x))
+        adcxq   %r9, %r15
+        adoxq   %r9, %r8
+        adcxq   %r9, %r8
+
+// Montgomery reduce windows 2 and 3 together
+
+        xorq    %r9, %r9
+        movq    $0x0000000100000000, %rdx
+        mulpadd(%r12,%r11,%r10)
+        mulpadd(%r13,%r12,%r11)
+        movq    $0xffffffff00000001, %rdx
+        mulpadd(%r14,%r13,%r10)
+        mulpadd(%r15,%r14,%r11)
+        adcxq   %r9, %r15
+        adoxq   %r9, %r8
+        adcxq   %r9, %r8
+
+// We now have a pre-reduced 5-word form [%r8; %r15;%r14;%r13;%r12]
+// Load non-trivial digits of p_256 = [v; 0; u; -1]
+
+        movl    $0x00000000ffffffff, ushort
+        movq    $0xffffffff00000001, v
+
+// Now do the subtraction (0,p_256-1) - (%r8,%r15,%r14,%r13,%r12) to get the carry
+
+        movq    $-2, d
+        subq    %r12, d
+        movq    u, d
+        sbbq    %r13, d
+        movl    $0, dshort
+        sbbq    %r14, d
+        movq    v, d
+        sbbq    %r15, d
+
+// This last comparison in the chain will actually even set the mask
+// for us, so we don't need to separately create it from the carry.
+// This means p_256 - 1 < (c,d1,d0,d5,d4), i.e. we are so far >= p_256
+
+        movl    $0, dshort
+        sbbq    %r8, d
+        andq    d, u
+        andq    d, v
+
+// Do a masked subtraction of p_256 and write back
+
+        subq    d, %r12
+        sbbq    u, %r13
+        sbbq    $0, %r14
+        sbbq    v, %r15
+
+        movq    %r12, (z)
+        movq    %r13, 8(z)
+        movq    %r14, 16(z)
+        movq    %r15, 24(z)
+
+// Restore registers and return
+
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_tomont_p256)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/bignum_tomont_p256_alt.S b/cbits/s2n/x86_att/bignum_tomont_p256_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/bignum_tomont_p256_alt.S
@@ -0,0 +1,203 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Convert to Montgomery form z := (2^256 * x) mod p_256
+// Input x[4]; output z[4]
+//
+//    extern void bignum_tomont_p256_alt(uint64_t z[static 4],
+//                                       const uint64_t x[static 4]);
+//
+// Standard x86-64 ABI: RDI = z, RSI = x
+// Microsoft x64 ABI:   RCX = z, RDX = x
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_tomont_p256_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_tomont_p256_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_tomont_p256_alt)
+        .text
+
+#define z %rdi
+#define x %rsi
+
+// Add %rcx * m into a register-pair (high,low) maintaining consistent
+// carry-catching with carry (negated, as bitmask) and using %rax and %rdx
+// as temporaries
+
+#define mulpadd(carry,high,low,m)       \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        subq    carry, %rdx ;             \
+        addq    %rax, low ;               \
+        adcq    %rdx, high ;              \
+        sbbq    carry, carry
+
+// Initial version assuming no carry-in
+
+#define mulpadi(carry,high,low,m)       \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        addq    %rax, low ;               \
+        adcq    %rdx, high ;              \
+        sbbq    carry, carry
+
+// End version not catching the top carry-out
+
+#define mulpade(carry,high,low,m)       \
+        movq    m, %rax ;                 \
+        mulq    %rcx;                    \
+        subq    carry, %rdx ;             \
+        addq    %rax, low ;               \
+        adcq    %rdx, high
+
+S2N_BN_SYMBOL(bignum_tomont_p256_alt):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Save more registers to play with
+
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+// Do row 0 computation, which is a bit different:
+// set up initial window [%r12,%r11,%r10,%r9,%r8] = y[0] * x
+// Unlike later, we only need a single carry chain
+
+        movl    $0x0000000000000003, %ecx
+        movq    (x), %rax
+        mulq    %rcx
+        movq    %rax, %r8
+        movq    %rdx, %r9
+
+        movq    8(x), %rax
+        mulq    %rcx
+        xorl    %r10d, %r10d
+        addq    %rax, %r9
+        adcq    %rdx, %r10
+
+        movq    16(x), %rax
+        mulq    %rcx
+        xorl    %r11d, %r11d
+        addq    %rax, %r10
+        adcq    %rdx, %r11
+
+        movq    24(x), %rax
+        mulq    %rcx
+        xorl    %r12d, %r12d
+        addq    %rax, %r11
+        adcq    %rdx, %r12
+
+// Add row 1
+
+        movq    $0xfffffffbffffffff, %rcx
+        xorl    %r13d, %r13d
+        mulpadi(%r14,%r10,%r9,(x))
+        mulpadd(%r14,%r11,%r10,8(x))
+        mulpadd(%r14,%r12,%r11,16(x))
+        mulpade(%r14,%r13,%r12,24(x))
+
+// Montgomery reduce windows 0 and 1 together
+
+        xorl    %r14d, %r14d
+        movq    $0x0000000100000000, %rcx
+        mulpadi(%r15,%r10,%r9,%r8)
+        mulpadd(%r15,%r11,%r10,%r9)
+        notq    %rcx
+        leaq    2(%rcx), %rcx
+        mulpadd(%r15,%r12,%r11,%r8)
+        mulpade(%r15,%r13,%r12,%r9)
+        adcq    %r14, %r14
+
+// Add row 2
+
+        movq    $0xfffffffffffffffe, %rcx
+        xorl    %r15d, %r15d
+        mulpadi(%r8,%r11,%r10,(x))
+        mulpadd(%r8,%r12,%r11,8(x))
+        mulpadd(%r8,%r13,%r12,16(x))
+        mulpade(%r8,%r14,%r13,24(x))
+        adcq    %r15, %r15
+
+// Add row 3
+
+        movq    $0x00000004fffffffd, %rcx
+        xorl    %r8d, %r8d
+        mulpadi(%r9,%r12,%r11,(x))
+        mulpadd(%r9,%r13,%r12,8(x))
+        mulpadd(%r9,%r14,%r13,16(x))
+        mulpade(%r9,%r15,%r14,24(x))
+        adcq    %r8, %r8
+
+// Montgomery reduce windows 2 and 3 together
+
+        movq    $0x0000000100000000, %rcx
+        mulpadi(%r9,%r12,%r11,%r10)
+        mulpadd(%r9,%r13,%r12,%r11)
+        notq    %rcx
+        leaq    2(%rcx), %rcx
+        mulpadd(%r9,%r14,%r13,%r10)
+        mulpadd(%r9,%r15,%r14,%r11)
+        subq    %r9, %r8
+
+// We now have a pre-reduced 5-word form [%r8; %r15;%r14;%r13;%r12]
+// Load [%rax;%r11;%r9;%rcx;%rdx] = 2^320 - p_256, re-using earlier numbers a bit
+// Do [%rax;%r11;%r9;%rcx;%rdx] = [%r8;%r15;%r14;%r13;%r12] + (2^320 - p_256)
+
+        xorl    %edx, %edx
+        leaq    -1(%rdx), %r9
+        incq    %rdx
+        addq    %r12, %rdx
+        decq    %rcx
+        adcq    %r13, %rcx
+        movq    %r9, %rax
+        adcq    %r14, %r9
+        movl    $0x00000000fffffffe, %r11d
+        adcq    %r15, %r11
+        adcq    %r8, %rax
+
+// Now carry is set if r + (2^320 - p_256) >= 2^320, i.e. r >= p_256
+// where r is the pre-reduced form. So conditionally select the
+// output accordingly.
+
+        cmovcq  %rdx, %r12
+        cmovcq  %rcx, %r13
+        cmovcq  %r9, %r14
+        cmovcq  %r11, %r15
+
+// Write back reduced value
+
+        movq    %r12, (z)
+        movq    %r13, 8(z)
+        movq    %r14, 16(z)
+        movq    %r15, 24(z)
+
+// Restore registers and return
+
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(bignum_tomont_p256_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/edwards25519_encode.S b/cbits/s2n/x86_att/edwards25519_encode.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/edwards25519_encode.S
@@ -0,0 +1,86 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Encode edwards25519 point into compressed form as 256-bit number
+// Input p[8]; output z[32] (bytes)
+//
+//    extern void edwards25519_encode(uint8_t z[static 32],
+//                                    const uint64_t p[static 8]);
+//
+// This assumes that the input buffer p points to a pair of 256-bit
+// numbers x (at p) and y (at p+4) representing a point (x,y) on the
+// edwards25519 curve. It is assumed that both x and y are < p_25519
+// but there is no checking of this, nor of the fact that (x,y) is
+// in fact on the curve.
+//
+// The output in z is a little-endian array of bytes corresponding to
+// the standard compressed encoding of a point as 2^255 * x_0 + y
+// where x_0 is the least significant bit of x.
+// See "https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2"
+// In this implementation, y is simply truncated to 255 bits, but if
+// it is reduced mod p_25519 as expected this does not affect values.
+//
+// Standard x86-64 ABI: RDI = z, RSI = p
+// Microsoft x64 ABI:   RCX = z, RDX = p
+// ----------------------------------------------------------------------------
+
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_encode)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_encode)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_encode)
+        .text
+
+#define z %rdi
+#define p %rsi
+#define y0 %rax
+#define y1 %rcx
+#define y2 %rdx
+#define y3 %r8
+#define xb %r9
+
+S2N_BN_SYMBOL(edwards25519_encode):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Load lowest word of x coordinate in xb and full y as [y3;y2;y1;y0].
+
+        movq    (p), xb
+        movq    32(p), y0
+        movq    40(p), y1
+        movq    48(p), y2
+        movq    56(p), y3
+
+// Compute the encoded form, making the LSB of x the MSB of the encoding
+
+        btr     $63, y3
+        shlq    $63, xb
+        orq     xb, y3
+
+// Store back (by the word, since x86 is little-endian anyway)
+
+        movq    y0, (z)
+        movq    y1, 8(z)
+        movq    y2, 16(z)
+        movq    y3, 24(z)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_encode)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/cbits/s2n/x86_att/edwards25519_scalarmulbase.S b/cbits/s2n/x86_att/edwards25519_scalarmulbase.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/edwards25519_scalarmulbase.S
@@ -0,0 +1,9926 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Scalar multiplication for the edwards25519 standard basepoint
+// Input scalar[4]; output res[8]
+//
+// extern void edwards25519_scalarmulbase
+//   (uint64_t res[static 8],const uint64_t scalar[static 4]);
+//
+// Given a scalar n, returns point (X,Y) = n * B where B = (...,4/5) is
+// the standard basepoint for the edwards25519 (Ed25519) curve.
+//
+// Standard x86-64 ABI: RDI = res, RSI = scalar
+// Microsoft x64 ABI:   RCX = res, RDX = scalar
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_scalarmulbase)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_scalarmulbase)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_scalarmulbase)
+
+        .text
+        .balign 32
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for result and temporaries on stack with some aliasing.
+// The result "resx" assumes the "res" pointer has been preloaded into %rbp.
+
+#define resx (0*NUMSIZE)(%rbp)
+#define resy (1*NUMSIZE)(%rbp)
+
+#define scalar (0*NUMSIZE)(%rsp)
+
+#define tabent (1*NUMSIZE)(%rsp)
+#define ymx_2 (1*NUMSIZE)(%rsp)
+#define xpy_2 (2*NUMSIZE)(%rsp)
+#define kxy_2 (3*NUMSIZE)(%rsp)
+
+#define t0 (4*NUMSIZE)(%rsp)
+#define t1 (5*NUMSIZE)(%rsp)
+#define t2 (6*NUMSIZE)(%rsp)
+#define t3 (7*NUMSIZE)(%rsp)
+#define t4 (8*NUMSIZE)(%rsp)
+#define t5 (9*NUMSIZE)(%rsp)
+
+#define acc (10*NUMSIZE)(%rsp)
+#define x_1 (10*NUMSIZE)(%rsp)
+#define y_1 (11*NUMSIZE)(%rsp)
+#define z_1 (12*NUMSIZE)(%rsp)
+#define w_1 (13*NUMSIZE)(%rsp)
+#define x_3 (10*NUMSIZE)(%rsp)
+#define y_3 (11*NUMSIZE)(%rsp)
+#define z_3 (12*NUMSIZE)(%rsp)
+#define w_3 (13*NUMSIZE)(%rsp)
+
+// Stable homes for the input result pointer, and other variables
+
+#define res  14*NUMSIZE(%rsp)
+
+#define i  14*NUMSIZE+8(%rsp)
+
+#define bias  14*NUMSIZE+16(%rsp)
+
+#define bf  14*NUMSIZE+24(%rsp)
+#define ix  14*NUMSIZE+24(%rsp)
+
+#define tab  15*NUMSIZE(%rsp)
+
+// Total size to reserve on the stack
+
+#define NSPACE 488
+
+// Syntactic variants to make x86_att version simpler to generate
+
+#define SCALAR 0
+#define TABENT (1*NUMSIZE)
+#define ACC (10*NUMSIZE)
+#define X3 (10*NUMSIZE)
+#define Z3 (12*NUMSIZE)
+#define W3 (13*NUMSIZE)
+
+// Macro wrapping up the basic field multiplication, only trivially
+// different from a pure function call to bignum_mul_p25519.
+
+#define mul_p25519(P0,P1,P2)                    \
+        xorl   %esi, %esi ;                        \
+        movq   P2, %rdx ;                       \
+        mulxq  P1, %r8, %r9 ;                    \
+        mulxq  0x8+P1, %rax, %r10 ;              \
+        addq   %rax, %r9 ;                         \
+        mulxq  0x10+P1, %rax, %r11 ;             \
+        adcq   %rax, %r10 ;                        \
+        mulxq  0x18+P1, %rax, %r12 ;             \
+        adcq   %rax, %r11 ;                        \
+        adcq   %rsi, %r12 ;                        \
+        xorl   %esi, %esi ;                        \
+        movq   0x8+P2, %rdx ;                   \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r9 ;                         \
+        adoxq  %rbx, %r10 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x18+P1, %rax, %r13 ;             \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rsi, %r13 ;                        \
+        adcxq  %rsi, %r13 ;                        \
+        xorl   %esi, %esi ;                        \
+        movq   0x10+P2, %rdx ;                  \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rbx, %r13 ;                        \
+        mulxq  0x18+P1, %rax, %r14 ;             \
+        adcxq  %rax, %r13 ;                        \
+        adoxq  %rsi, %r14 ;                        \
+        adcxq  %rsi, %r14 ;                        \
+        xorl   %esi, %esi ;                        \
+        movq   0x18+P2, %rdx ;                  \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rbx, %r13 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r13 ;                        \
+        adoxq  %rbx, %r14 ;                        \
+        mulxq  0x18+P1, %rax, %r15 ;             \
+        adcxq  %rax, %r14 ;                        \
+        adoxq  %rsi, %r15 ;                        \
+        adcxq  %rsi, %r15 ;                        \
+        movl   $0x26, %edx ;                       \
+        xorl   %esi, %esi ;                        \
+        mulxq  %r12, %rax, %rbx ;                   \
+        adcxq  %rax, %r8 ;                         \
+        adoxq  %rbx, %r9 ;                         \
+        mulxq  %r13, %rax, %rbx ;                   \
+        adcxq  %rax, %r9 ;                         \
+        adoxq  %rbx, %r10 ;                        \
+        mulxq  %r14, %rax, %rbx ;                   \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  %r15, %rax, %r12 ;                   \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rsi, %r12 ;                        \
+        adcxq  %rsi, %r12 ;                        \
+        shldq  $0x1, %r11, %r12 ;                   \
+        movl   $0x13, %edx ;                       \
+        incq   %r12;                             \
+        bts    $63, %r11 ;                         \
+        mulxq  %r12, %rax, %rbx ;                   \
+        addq   %rax, %r8 ;                         \
+        adcq   %rbx, %r9 ;                         \
+        adcq   %rsi, %r10 ;                        \
+        adcq   %rsi, %r11 ;                        \
+        sbbq   %rax, %rax ;                        \
+        notq   %rax;                             \
+        andq   %rdx, %rax ;                        \
+        subq   %rax, %r8 ;                         \
+        sbbq   %rsi, %r9 ;                         \
+        sbbq   %rsi, %r10 ;                        \
+        sbbq   %rsi, %r11 ;                        \
+        btr    $63, %r11 ;                         \
+        movq   %r8, P0 ;                        \
+        movq   %r9, 0x8+P0 ;                    \
+        movq   %r10, 0x10+P0 ;                  \
+        movq   %r11, 0x18+P0
+
+// A version of multiplication that only guarantees output < 2 * p_25519.
+// This basically skips the +1 and final correction in quotient estimation.
+
+#define mul_4(P0,P1,P2)                         \
+        xorl   %ecx, %ecx ;                        \
+        movq   P2, %rdx ;                       \
+        mulxq  P1, %r8, %r9 ;                    \
+        mulxq  0x8+P1, %rax, %r10 ;              \
+        addq   %rax, %r9 ;                         \
+        mulxq  0x10+P1, %rax, %r11 ;             \
+        adcq   %rax, %r10 ;                        \
+        mulxq  0x18+P1, %rax, %r12 ;             \
+        adcq   %rax, %r11 ;                        \
+        adcq   %rcx, %r12 ;                        \
+        xorl   %ecx, %ecx ;                        \
+        movq   0x8+P2, %rdx ;                   \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r9 ;                         \
+        adoxq  %rbx, %r10 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x18+P1, %rax, %r13 ;             \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rcx, %r13 ;                        \
+        adcxq  %rcx, %r13 ;                        \
+        xorl   %ecx, %ecx ;                        \
+        movq   0x10+P2, %rdx ;                  \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rbx, %r13 ;                        \
+        mulxq  0x18+P1, %rax, %r14 ;             \
+        adcxq  %rax, %r13 ;                        \
+        adoxq  %rcx, %r14 ;                        \
+        adcxq  %rcx, %r14 ;                        \
+        xorl   %ecx, %ecx ;                        \
+        movq   0x18+P2, %rdx ;                  \
+        mulxq  P1, %rax, %rbx ;                  \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rbx, %r12 ;                        \
+        mulxq  0x8+P1, %rax, %rbx ;              \
+        adcxq  %rax, %r12 ;                        \
+        adoxq  %rbx, %r13 ;                        \
+        mulxq  0x10+P1, %rax, %rbx ;             \
+        adcxq  %rax, %r13 ;                        \
+        adoxq  %rbx, %r14 ;                        \
+        mulxq  0x18+P1, %rax, %r15 ;             \
+        adcxq  %rax, %r14 ;                        \
+        adoxq  %rcx, %r15 ;                        \
+        adcxq  %rcx, %r15 ;                        \
+        movl   $0x26, %edx ;                       \
+        xorl   %ecx, %ecx ;                        \
+        mulxq  %r12, %rax, %rbx ;                   \
+        adcxq  %rax, %r8 ;                         \
+        adoxq  %rbx, %r9 ;                         \
+        mulxq  %r13, %rax, %rbx ;                   \
+        adcxq  %rax, %r9 ;                         \
+        adoxq  %rbx, %r10 ;                        \
+        mulxq  %r14, %rax, %rbx ;                   \
+        adcxq  %rax, %r10 ;                        \
+        adoxq  %rbx, %r11 ;                        \
+        mulxq  %r15, %rax, %r12 ;                   \
+        adcxq  %rax, %r11 ;                        \
+        adoxq  %rcx, %r12 ;                        \
+        adcxq  %rcx, %r12 ;                        \
+        shldq  $0x1, %r11, %r12 ;                   \
+        btr    $0x3f, %r11 ;                       \
+        movl   $0x13, %edx ;                       \
+        imulq  %r12, %rdx ;                        \
+        addq   %rdx, %r8 ;                         \
+        adcq   %rcx, %r9 ;                         \
+        adcq   %rcx, %r10 ;                        \
+        adcq   %rcx, %r11 ;                        \
+        movq   %r8, P0 ;                        \
+        movq   %r9, 0x8+P0 ;                    \
+        movq   %r10, 0x10+P0 ;                  \
+        movq   %r11, 0x18+P0
+
+// Modular subtraction with double modulus 2 * p_25519 = 2^256 - 38
+
+#define sub_twice4(P0,P1,P2)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ebx, %ebx ;                       \
+        subq    P2, %r8 ;                       \
+        movq    8+P1, %r9 ;                     \
+        sbbq    8+P2, %r9 ;                     \
+        movl    $38, %ecx ;                        \
+        movq    16+P1, %r10 ;                   \
+        sbbq    16+P2, %r10 ;                   \
+        movq    24+P1, %rax ;                   \
+        sbbq    24+P2, %rax ;                   \
+        cmovncq %rbx, %rcx ;                       \
+        subq    %rcx, %r8 ;                        \
+        sbbq    %rbx, %r9 ;                        \
+        sbbq    %rbx, %r10 ;                       \
+        sbbq    %rbx, %rax ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 8+P0 ;                     \
+        movq    %r10, 16+P0 ;                   \
+        movq    %rax, 24+P0
+
+// Modular addition and doubling with double modulus 2 * p_25519 = 2^256 - 38.
+// This only ensures that the result fits in 4 digits, not that it is reduced
+// even w.r.t. double modulus. The result is always correct modulo provided
+// the sum of the inputs is < 2^256 + 2^256 - 38, so in particular provided
+// at least one of them is reduced double modulo.
+
+#define add_twice4(P0,P1,P2)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    P2, %r8 ;                       \
+        movq    0x8+P1, %r9 ;                   \
+        adcq    0x8+P2, %r9 ;                   \
+        movq    0x10+P1, %r10 ;                 \
+        adcq    0x10+P2, %r10 ;                 \
+        movq    0x18+P1, %r11 ;                 \
+        adcq    0x18+P2, %r11 ;                 \
+        movl    $38, %eax ;                        \
+        cmovncq %rcx, %rax ;                       \
+        addq    %rax, %r8 ;                        \
+        adcq    %rcx, %r9 ;                        \
+        adcq    %rcx, %r10 ;                       \
+        adcq    %rcx, %r11 ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 0x8+P0 ;                   \
+        movq    %r10, 0x10+P0 ;                 \
+        movq    %r11, 0x18+P0
+
+#define double_twice4(P0,P1)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    %r8, %r8 ;                         \
+        movq    0x8+P1, %r9 ;                   \
+        adcq    %r9, %r9 ;                         \
+        movq    0x10+P1, %r10 ;                 \
+        adcq    %r10, %r10 ;                       \
+        movq    0x18+P1, %r11 ;                 \
+        adcq    %r11, %r11 ;                       \
+        movl    $38, %eax ;                        \
+        cmovncq %rcx, %rax ;                       \
+        addq    %rax, %r8 ;                        \
+        adcq    %rcx, %r9 ;                        \
+        adcq    %rcx, %r10 ;                       \
+        adcq    %rcx, %r11 ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 0x8+P0 ;                   \
+        movq    %r10, 0x10+P0 ;                 \
+        movq    %r11, 0x18+P0
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase):
+        CFI_START
+        _CET_ENDBR
+
+// In this case the Windows form literally makes a subroutine call.
+// This avoids hassle arising from keeping code and data together.
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        CFI_CALL(Ledwards25519_scalarmulbase_standard)
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase)
+
+S2N_BN_FUNCTION_TYPE_DIRECTIVE(Ledwards25519_scalarmulbase_standard)
+
+Ledwards25519_scalarmulbase_standard:
+        CFI_START
+#endif
+
+// Save registers, make room for temps, preserve input arguments.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+        CFI_DEC_RSP(NSPACE)
+
+// Move the output pointer to a stable place
+
+        movq    %rdi, res
+
+// Copy the input scalar x to its local variable while reducing it
+// modulo 2^252 + m where m = 27742317777372353535851937790883648493;
+// this is the order of the basepoint so this doesn't change the result.
+// First do q = floor(x/2^252) and x' = x - q * (2^252 + m), which gives
+// an initial result -15 * m <= x' < 2^252
+
+        movq    (%rsi), %r8
+        movq    8(%rsi), %r9
+        movq    16(%rsi), %r10
+        movq    24(%rsi), %r11
+
+        movq    %r11, %rcx
+        shrq    $60, %rcx
+
+        movq    $0x5812631a5cf5d3ed, %rax
+        mulq    %rcx
+        movq    %rax, %r12
+        movq    %rdx, %r13
+        movq    $0x14def9dea2f79cd6, %rax
+        mulq    %rcx
+        addq    %rax, %r13
+        adcq    $0, %rdx
+        shlq    $60, %rcx
+
+        subq    %r12, %r8
+        sbbq    %r13, %r9
+        sbbq    %rdx, %r10
+        sbbq    %rcx, %r11
+
+// If x' < 0 then just directly negate it; this makes sure the
+// reduced argument is strictly 0 <= x' < 2^252, but now we need
+// to record (done via bit 255 of the reduced scalar, which is
+// ignored in the main loop) when we negated so we can flip
+// the end result to compensate.
+
+        sbbq    %rax, %rax
+
+        xorq    %rax, %r8
+        xorq    %rax, %r9
+        xorq    %rax, %r10
+        xorq    %rax, %r11
+
+        negq    %rax
+        adcq    $0, %r8
+        adcq    $0, %r9
+        adcq    $0, %r10
+        adcq    $0, %r11
+
+        shlq    $63, %rax
+        orq     %rax, %r11
+
+// And before we store the scalar, test and reset bit 251 to
+// initialize the main loop just below.
+
+        movq    %r8, SCALAR(%rsp)
+        movq    %r9, SCALAR+8(%rsp)
+        movq    %r10, SCALAR+16(%rsp)
+        btr     $59, %r11
+        movq    %r11, SCALAR+24(%rsp)
+
+// The main part of the computation is in extended-projective coordinates
+// (X,Y,Z,T), representing an affine point on the edwards25519 curve
+// (x,y) via x = X/Z, y = Y/Z and x * y = T/Z (so X * Y = T * Z).
+// In comments B means the standard basepoint (x,4/5) =
+// (0x216....f25d51a,0x6666..666658).
+//
+// Initialize accumulator "acc" to either 0 or 2^251 * B depending on
+// bit 251 of the (reduced) scalar. That leaves bits 0..250 to handle.
+
+        leaq    S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant)(%rip), %r10
+        leaq    8*12(%r10), %r11
+
+        movq    (%r10), %rax
+        movq    (%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC(%rsp)
+
+        movq    8*1(%r10), %rax
+        movq    8*1(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+8(%rsp)
+
+        movq    8*2(%r10), %rax
+        movq    8*2(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+16(%rsp)
+
+        movq    8*3(%r10), %rax
+        movq    8*3(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+24(%rsp)
+
+        movq    8*4(%r10), %rax
+        movq    8*4(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+32(%rsp)
+
+        movq    8*5(%r10), %rax
+        movq    8*5(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+40(%rsp)
+
+        movq    8*6(%r10), %rax
+        movq    8*6(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+48(%rsp)
+
+        movq    8*7(%r10), %rax
+        movq    8*7(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+56(%rsp)
+
+        movl    $1, %eax
+        movq    %rax, ACC+64(%rsp)
+        movl    $0, %eax
+        movq    %rax, ACC+72(%rsp)
+        movq    %rax, ACC+80(%rsp)
+        movq    %rax, ACC+88(%rsp)
+
+        movq    8*8(%r10), %rax
+        movq    8*8(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+96(%rsp)
+
+        movq    8*9(%r10), %rax
+        movq    8*9(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+104(%rsp)
+
+        movq    8*10(%r10), %rax
+        movq    8*10(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+112(%rsp)
+
+        movq    8*11(%r10), %rax
+        movq    8*11(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+120(%rsp)
+
+// The counter "i" tracks the bit position for which the scalar has
+// already been absorbed, starting at 0 and going up in chunks of 4.
+//
+// The pointer "tab" points at the current block of the table for
+// multiples (2^i * j) * B at the current bit position i; 1 <= j <= 8.
+//
+// The bias is always either 0 and 1 and needs to be added to the
+// partially processed scalar implicitly. This is used to absorb 4 bits
+// of scalar per iteration from 3-bit table indexing by exploiting
+// negation: (16 * h + l) * B = (16 * (h + 1) - (16 - l)) * B is used
+// when l >= 9. Note that we can't have any bias left over at the
+// end because we made sure bit 251 is clear in the reduced scalar.
+
+        movq    $0, i
+        leaq    8*24(%r10), %rax
+        movq    %rax, tab
+        movq    $0, bias
+
+// Start of the main loop, repeated 63 times for i = 4, 8, ..., 252
+
+Ledwards25519_scalarmulbase_scalarloop:
+
+// Look at the next 4-bit field "bf", adding the previous bias as well.
+// Choose the table index "ix" as bf when bf <= 8 and 16 - bf for bf >= 9,
+// setting the bias to 1 for the next iteration in the latter case.
+
+        movq    i, %rax
+        movq    %rax, %rcx
+        shrq    $6, %rax
+        movq    (%rsp,%rax,8), %rax // Exploiting scalar = sp exactly
+        shrq    %cl, %rax
+        andq    $15, %rax
+        addq    bias, %rax
+        movq    %rax, bf
+
+        cmpq    $9, bf
+        sbbq    %rax, %rax
+        incq    %rax
+        movq    %rax, bias
+
+        movq    $16, %rdi
+        subq    bf, %rdi
+        cmpq    $0, bias
+        cmovzq  bf, %rdi
+        movq    %rdi, ix
+
+// Perform constant-time lookup in the table to get element number "ix".
+// The table entry for the affine point (x,y) is actually a triple
+// (y - x,x + y,2 * d * x * y) to precompute parts of the addition.
+// Note that "ix" can be 0, so we set up the appropriate identity first.
+
+        movl    $1, %eax
+        xorl    %ebx, %ebx
+        xorl    %ecx, %ecx
+        xorl    %edx, %edx
+        movl    $1, %r8d
+        xorl    %r9d, %r9d
+        xorl    %r10d, %r10d
+        xorl    %r11d, %r11d
+        xorl    %r12d, %r12d
+        xorl    %r13d, %r13d
+        xorl    %r14d, %r14d
+        xorl    %r15d, %r15d
+
+        movq    tab, %rbp
+
+        cmpq    $1, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $2, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $3, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $4, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $5, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $6, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $7, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $8, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+
+        addq    $96, %rbp
+        movq    %rbp, tab
+
+// We now have the triple from the table in registers as follows
+//
+//      [%rdx;%rcx;%rbx;%rax] = y - x
+//      [%r11;%r10;%r9;%r8] = x + y
+//      [%r15;%r14;%r13;%r12] = 2 * d * x * y
+//
+// In case bias = 1 we need to negate this. For Edwards curves
+// -(x,y) = (-x,y), i.e. we need to negate the x coordinate.
+// In this processed encoding, that amounts to swapping the
+// first two fields and negating the third.
+//
+// The optional negation here also pretends bias = 0 whenever
+// ix = 0 so that it doesn't need to handle the case of zero
+// inputs, since no non-trivial table entries are zero. Note
+// that in the zero case the whole negation is trivial, and
+// so indeed is the swapping.
+
+        cmpq    $0, bias
+
+        movq    %rax, %rsi
+        cmovnzq %r8, %rsi
+        cmovnzq %rax, %r8
+        movq    %rsi, TABENT(%rsp)
+        movq    %r8, TABENT+32(%rsp)
+
+        movq    %rbx, %rsi
+        cmovnzq %r9, %rsi
+        cmovnzq %rbx, %r9
+        movq    %rsi, TABENT+8(%rsp)
+        movq    %r9, TABENT+40(%rsp)
+
+        movq    %rcx, %rsi
+        cmovnzq %r10, %rsi
+        cmovnzq %rcx, %r10
+        movq    %rsi, TABENT+16(%rsp)
+        movq    %r10, TABENT+48(%rsp)
+
+        movq    %rdx, %rsi
+        cmovnzq %r11, %rsi
+        cmovnzq %rdx, %r11
+        movq    %rsi, TABENT+24(%rsp)
+        movq    %r11, TABENT+56(%rsp)
+
+        movq    $-19, %rax
+        movq    $-1, %rbx
+        movq    $-1, %rcx
+        movq    $0x7fffffffffffffff, %rdx
+        subq    %r12, %rax
+        sbbq    %r13, %rbx
+        sbbq    %r14, %rcx
+        sbbq    %r15, %rdx
+
+        movq    ix, %r8
+        movq    bias, %r9
+        testq   %r8, %r8
+        cmovzq  %r8, %r9
+        testq   %r9, %r9
+
+        cmovzq  %r12, %rax
+        cmovzq  %r13, %rbx
+        cmovzq  %r14, %rcx
+        cmovzq  %r15, %rdx
+        movq    %rax, TABENT+64(%rsp)
+        movq    %rbx, TABENT+72(%rsp)
+        movq    %rcx, TABENT+80(%rsp)
+        movq    %rdx, TABENT+88(%rsp)
+
+// Extended-projective and precomputed mixed addition.
+// This is effectively the same as calling the standalone
+// function edwards25519_pepadd(acc,acc,tabent), but we
+// only retain slightly weaker normalization < 2 * p_25519
+// throughout the inner loop, so the computation is
+// slightly different, and faster overall.
+
+        double_twice4(t0,z_1)
+        sub_twice4(t1,y_1,x_1)
+        add_twice4(t2,y_1,x_1)
+        mul_4(t3,w_1,kxy_2)
+        mul_4(t1,t1,ymx_2)
+        mul_4(t2,t2,xpy_2)
+        sub_twice4(t4,t0,t3)
+        add_twice4(t0,t0,t3)
+        sub_twice4(t5,t2,t1)
+        add_twice4(t1,t2,t1)
+        mul_4(z_3,t4,t0)
+        mul_4(x_3,t5,t4)
+        mul_4(y_3,t0,t1)
+        mul_4(w_3,t5,t1)
+
+// End of the main loop; move on by 4 bits.
+
+        addq    $4, i
+        cmpq    $252, i
+        jc      Ledwards25519_scalarmulbase_scalarloop
+
+// Insert the optional negation of the projective X coordinate, and
+// so by extension the final affine x coordinate x = X/Z and thus
+// the point P = (x,y). We only know X < 2 * p_25519, so we do the
+// negation as 2 * p_25519 - X to keep it nonnegative. From this
+// point on we don't need any normalization of the coordinates
+// except for making sure that they fit in 4 digits.
+
+        movq    X3(%rsp), %r8
+        movq    X3+8(%rsp), %r9
+        movq    X3+16(%rsp), %r10
+        movq    X3+24(%rsp), %r11
+        movq    $0xffffffffffffffda, %r12
+        subq    %r8, %r12
+        movq    $0xffffffffffffffff, %r13
+        sbbq    %r9, %r13
+        movq    $0xffffffffffffffff, %r14
+        sbbq    %r10, %r14
+        movq    $0xffffffffffffffff, %r15
+        sbbq    %r11, %r15
+        movq    SCALAR+24(%rsp), %rax
+        btq     $63, %rax
+        cmovcq  %r12, %r8
+        cmovcq  %r13, %r9
+        cmovcq  %r14, %r10
+        cmovcq  %r15, %r11
+        movq    %r8, X3(%rsp)
+        movq    %r9, X3+8(%rsp)
+        movq    %r10, X3+16(%rsp)
+        movq    %r11, X3+24(%rsp)
+
+// Now we need to map out of the extended-projective representation
+// (X,Y,Z,W) back to the affine form (x,y) = (X/Z,Y/Z). This means
+// first calling the modular inverse to get w_3 = 1/z_3.
+
+        leaq    W3(%rsp), %rdi
+        leaq    Z3(%rsp), %rsi
+
+// Inline copy of bignum_inv_p25519, identical except for stripping out
+// the prologue and epilogue saving and restoring registers and making
+// and reclaiming room on the stack. For more details and explanations see
+// "x86/curve25519/bignum_inv_p25519.S". Note that the stack it uses for
+// its own temporaries is 208 bytes, so it has no effect on variables
+// that are needed in the rest of our computation here: res, x_3, y_3,
+// z_3 and w_3.
+
+        movq    %rdi, 0xc0(%rsp)
+        xorl    %eax, %eax
+        leaq    -0x13(%rax), %rcx
+        notq    %rax
+        movq    %rcx, (%rsp)
+        movq    %rax, 0x8(%rsp)
+        movq    %rax, 0x10(%rsp)
+        btr     $0x3f, %rax
+        movq    %rax, 0x18(%rsp)
+        movq    (%rsi), %rdx
+        movq    0x8(%rsi), %rcx
+        movq    0x10(%rsi), %r8
+        movq    0x18(%rsi), %r9
+        movl    $0x1, %eax
+        xorl    %r10d, %r10d
+        bts     $0x3f, %r9
+        adcq    %r10, %rax
+        imulq   $0x13, %rax, %rax
+        addq    %rax, %rdx
+        adcq    %r10, %rcx
+        adcq    %r10, %r8
+        adcq    %r10, %r9
+        movl    $0x13, %eax
+        cmovbq  %r10, %rax
+        subq    %rax, %rdx
+        sbbq    %r10, %rcx
+        sbbq    %r10, %r8
+        sbbq    %r10, %r9
+        btr     $0x3f, %r9
+        movq    %rdx, 0x20(%rsp)
+        movq    %rcx, 0x28(%rsp)
+        movq    %r8, 0x30(%rsp)
+        movq    %r9, 0x38(%rsp)
+        xorl    %eax, %eax
+        movq    %rax, 0x40(%rsp)
+        movq    %rax, 0x48(%rsp)
+        movq    %rax, 0x50(%rsp)
+        movq    %rax, 0x58(%rsp)
+        movabsq $0xa0f99e2375022099, %rax
+        movq    %rax, 0x60(%rsp)
+        movabsq $0xa8c68f3f1d132595, %rax
+        movq    %rax, 0x68(%rsp)
+        movabsq $0x6c6c893805ac5242, %rax
+        movq    %rax, 0x70(%rsp)
+        movabsq $0x276508b241770615, %rax
+        movq    %rax, 0x78(%rsp)
+        movq    $0xa,  0x90(%rsp)
+        movq    $0x1,  0x98(%rsp)
+        jmp     Ledwards25519_scalarmulbase_midloop
+Ledwards25519_scalarmulbase_inverseloop:
+        movq    %r8, %r9
+        sarq    $0x3f, %r9
+        xorq    %r9, %r8
+        subq    %r9, %r8
+        movq    %r10, %r11
+        sarq    $0x3f, %r11
+        xorq    %r11, %r10
+        subq    %r11, %r10
+        movq    %r12, %r13
+        sarq    $0x3f, %r13
+        xorq    %r13, %r12
+        subq    %r13, %r12
+        movq    %r14, %r15
+        sarq    $0x3f, %r15
+        xorq    %r15, %r14
+        subq    %r15, %r14
+        movq    %r8, %rax
+        andq    %r9, %rax
+        movq    %r10, %rdi
+        andq    %r11, %rdi
+        addq    %rax, %rdi
+        movq    %rdi, 0x80(%rsp)
+        movq    %r12, %rax
+        andq    %r13, %rax
+        movq    %r14, %rsi
+        andq    %r15, %rsi
+        addq    %rax, %rsi
+        movq    %rsi, 0x88(%rsp)
+        xorl    %ebx, %ebx
+        movq    (%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        movq    0x20(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        xorl    %ebp, %ebp
+        movq    (%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x20(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        xorl    %ecx, %ecx
+        movq    0x8(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x28(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        shrdq   $0x3b, %rbx, %rdi
+        movq    %rdi, (%rsp)
+        xorl    %edi, %edi
+        movq    0x8(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rbp
+        adcq    %rdx, %rdi
+        movq    0x28(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rdi
+        shrdq   $0x3b, %rbp, %rsi
+        movq    %rsi, 0x20(%rsp)
+        xorl    %esi, %esi
+        movq    0x10(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rsi
+        movq    0x30(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rdx, %rsi
+        shrdq   $0x3b, %rcx, %rbx
+        movq    %rbx, 0x8(%rsp)
+        xorl    %ebx, %ebx
+        movq    0x10(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        movq    0x30(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        shrdq   $0x3b, %rdi, %rbp
+        movq    %rbp, 0x28(%rsp)
+        movq    0x18(%rsp), %rax
+        xorq    %r9, %rax
+        movq    %rax, %rbp
+        sarq    $0x3f, %rbp
+        andq    %r8, %rbp
+        negq    %rbp
+        mulq    %r8
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x38(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %rax, %rdx
+        sarq    $0x3f, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %rbp
+        mulq    %r10
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        shrdq   $0x3b, %rsi, %rcx
+        movq    %rcx, 0x10(%rsp)
+        shrdq   $0x3b, %rbp, %rsi
+        movq    0x18(%rsp), %rax
+        movq    %rsi, 0x18(%rsp)
+        xorq    %r13, %rax
+        movq    %rax, %rsi
+        sarq    $0x3f, %rsi
+        andq    %r12, %rsi
+        negq    %rsi
+        mulq    %r12
+        addq    %rax, %rbx
+        adcq    %rdx, %rsi
+        movq    0x38(%rsp), %rax
+        xorq    %r15, %rax
+        movq    %rax, %rdx
+        sarq    $0x3f, %rdx
+        andq    %r14, %rdx
+        subq    %rdx, %rsi
+        mulq    %r14
+        addq    %rax, %rbx
+        adcq    %rdx, %rsi
+        shrdq   $0x3b, %rbx, %rdi
+        movq    %rdi, 0x30(%rsp)
+        shrdq   $0x3b, %rsi, %rbx
+        movq    %rbx, 0x38(%rsp)
+        movq    0x80(%rsp), %rbx
+        movq    0x88(%rsp), %rbp
+        xorl    %ecx, %ecx
+        movq    0x40(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x60(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        xorl    %esi, %esi
+        movq    0x40(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rbx, 0x40(%rsp)
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    0x60(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    %rbp, 0x60(%rsp)
+        xorl    %ebx, %ebx
+        movq    0x48(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        movq    0x68(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        xorl    %ebp, %ebp
+        movq    0x48(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rcx, 0x48(%rsp)
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x68(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    %rsi, 0x68(%rsp)
+        xorl    %ecx, %ecx
+        movq    0x50(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x70(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        xorl    %esi, %esi
+        movq    0x50(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rbx, 0x50(%rsp)
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    0x70(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    %rbp, 0x70(%rsp)
+        movq    0x58(%rsp), %rax
+        xorq    %r9, %rax
+        movq    %r9, %rbx
+        andq    %r8, %rbx
+        negq    %rbx
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        movq    0x78(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %r11, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %rbx
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rbx, %rdx
+        movq    %rdx, %rbx
+        shldq   $0x1, %rcx, %rdx
+        sarq    $0x3f, %rbx
+        addq    %rbx, %rdx
+        movl    $0x13, %eax
+        imulq   %rdx
+        movq    0x40(%rsp), %r8
+        addq    %rax, %r8
+        movq    %r8, 0x40(%rsp)
+        movq    0x48(%rsp), %r8
+        adcq    %rdx, %r8
+        movq    %r8, 0x48(%rsp)
+        movq    0x50(%rsp), %r8
+        adcq    %rbx, %r8
+        movq    %r8, 0x50(%rsp)
+        adcq    %rbx, %rcx
+        shlq    $0x3f, %rax
+        addq    %rax, %rcx
+        movq    0x58(%rsp), %rax
+        movq    %rcx, 0x58(%rsp)
+        xorq    %r13, %rax
+        movq    %r13, %rcx
+        andq    %r12, %rcx
+        negq    %rcx
+        mulq    %r12
+        addq    %rax, %rsi
+        adcq    %rdx, %rcx
+        movq    0x78(%rsp), %rax
+        xorq    %r15, %rax
+        movq    %r15, %rdx
+        andq    %r14, %rdx
+        subq    %rdx, %rcx
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rcx, %rdx
+        movq    %rdx, %rcx
+        shldq   $0x1, %rsi, %rdx
+        sarq    $0x3f, %rcx
+        movl    $0x13, %eax
+        addq    %rcx, %rdx
+        imulq   %rdx
+        movq    0x60(%rsp), %r8
+        addq    %rax, %r8
+        movq    %r8, 0x60(%rsp)
+        movq    0x68(%rsp), %r8
+        adcq    %rdx, %r8
+        movq    %r8, 0x68(%rsp)
+        movq    0x70(%rsp), %r8
+        adcq    %rcx, %r8
+        movq    %r8, 0x70(%rsp)
+        adcq    %rcx, %rsi
+        shlq    $0x3f, %rax
+        addq    %rax, %rsi
+        movq    %rsi, 0x78(%rsp)
+Ledwards25519_scalarmulbase_midloop:
+        movq    0x98(%rsp), %rsi
+        movq    (%rsp), %rdx
+        movq    0x20(%rsp), %rcx
+        movq    %rdx, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    $0xfffffffffffffffe, %rax
+        xorl    %ebp, %ebp
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %rdx
+        leaq    (%rcx,%rax), %rdi
+        shlq    $0x16, %rdx
+        shlq    $0x16, %rdi
+        sarq    $0x2b, %rdx
+        sarq    $0x2b, %rdi
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %rbx
+        leaq    (%rcx,%rax), %rcx
+        sarq    $0x2a, %rbx
+        sarq    $0x2a, %rcx
+        movq    %rdx, 0xa0(%rsp)
+        movq    %rbx, 0xa8(%rsp)
+        movq    %rdi, 0xb0(%rsp)
+        movq    %rcx, 0xb8(%rsp)
+        movq    (%rsp), %r12
+        imulq   %r12, %rdi
+        imulq   %rdx, %r12
+        movq    0x20(%rsp), %r13
+        imulq   %r13, %rbx
+        imulq   %rcx, %r13
+        addq    %rbx, %r12
+        addq    %rdi, %r13
+        sarq    $0x14, %r12
+        sarq    $0x14, %r13
+        movq    %r12, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        movq    %r13, %rcx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    $0xfffffffffffffffe, %rax
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %r8
+        leaq    (%rcx,%rax), %r10
+        shlq    $0x16, %r8
+        shlq    $0x16, %r10
+        sarq    $0x2b, %r8
+        sarq    $0x2b, %r10
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %r15
+        leaq    (%rcx,%rax), %r11
+        sarq    $0x2a, %r15
+        sarq    $0x2a, %r11
+        movq    %r13, %rbx
+        movq    %r12, %rcx
+        imulq   %r8, %r12
+        imulq   %r15, %rbx
+        addq    %rbx, %r12
+        imulq   %r11, %r13
+        imulq   %r10, %rcx
+        addq    %rcx, %r13
+        sarq    $0x14, %r12
+        sarq    $0x14, %r13
+        movq    %r12, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        movq    %r13, %rcx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    0xa0(%rsp), %rax
+        imulq   %r8, %rax
+        movq    0xb0(%rsp), %rdx
+        imulq   %r15, %rdx
+        imulq   0xa8(%rsp), %r8
+        imulq   0xb8(%rsp), %r15
+        addq    %r8, %r15
+        leaq    (%rax,%rdx), %r9
+        movq    0xa0(%rsp), %rax
+        imulq   %r10, %rax
+        movq    0xb0(%rsp), %rdx
+        imulq   %r11, %rdx
+        imulq   0xa8(%rsp), %r10
+        imulq   0xb8(%rsp), %r11
+        addq    %r10, %r11
+        leaq    (%rax,%rdx), %r13
+        movq    $0xfffffffffffffffe, %rax
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %r8
+        leaq    (%rcx,%rax), %r12
+        shlq    $0x15, %r8
+        shlq    $0x15, %r12
+        sarq    $0x2b, %r8
+        sarq    $0x2b, %r12
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %r10
+        leaq    (%rcx,%rax), %r14
+        sarq    $0x2b, %r10
+        sarq    $0x2b, %r14
+        movq    %r9, %rax
+        imulq   %r8, %rax
+        movq    %r13, %rdx
+        imulq   %r10, %rdx
+        imulq   %r15, %r8
+        imulq   %r11, %r10
+        addq    %r8, %r10
+        leaq    (%rax,%rdx), %r8
+        movq    %r9, %rax
+        imulq   %r12, %rax
+        movq    %r13, %rdx
+        imulq   %r14, %rdx
+        imulq   %r15, %r12
+        imulq   %r11, %r14
+        addq    %r12, %r14
+        leaq    (%rax,%rdx), %r12
+        movq    %rsi, 0x98(%rsp)
+        decq     0x90(%rsp)
+        jne     Ledwards25519_scalarmulbase_inverseloop
+        movq    (%rsp), %rax
+        movq    0x20(%rsp), %rcx
+        imulq   %r8, %rax
+        imulq   %r10, %rcx
+        addq    %rcx, %rax
+        sarq    $0x3f, %rax
+        movq    %r8, %r9
+        sarq    $0x3f, %r9
+        xorq    %r9, %r8
+        subq    %r9, %r8
+        xorq    %rax, %r9
+        movq    %r10, %r11
+        sarq    $0x3f, %r11
+        xorq    %r11, %r10
+        subq    %r11, %r10
+        xorq    %rax, %r11
+        movq    %r12, %r13
+        sarq    $0x3f, %r13
+        xorq    %r13, %r12
+        subq    %r13, %r12
+        xorq    %rax, %r13
+        movq    %r14, %r15
+        sarq    $0x3f, %r15
+        xorq    %r15, %r14
+        subq    %r15, %r14
+        xorq    %rax, %r15
+        movq    %r8, %rax
+        andq    %r9, %rax
+        movq    %r10, %r12
+        andq    %r11, %r12
+        addq    %rax, %r12
+        xorl    %r13d, %r13d
+        movq    0x40(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        movq    0x60(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        xorl    %r14d, %r14d
+        movq    0x48(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r13
+        adcq    %rdx, %r14
+        movq    0x68(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r13
+        adcq    %rdx, %r14
+        xorl    %r15d, %r15d
+        movq    0x50(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r14
+        adcq    %rdx, %r15
+        movq    0x70(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r14
+        adcq    %rdx, %r15
+        movq    0x58(%rsp), %rax
+        xorq    %r9, %rax
+        andq    %r8, %r9
+        negq    %r9
+        mulq    %r8
+        addq    %rax, %r15
+        adcq    %rdx, %r9
+        movq    0x78(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %r11, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %r9
+        mulq    %r10
+        addq    %rax, %r15
+        adcq    %rdx, %r9
+        movq    %r9, %rax
+        shldq   $0x1, %r15, %rax
+        sarq    $0x3f, %r9
+        movl    $0x13, %ebx
+        leaq    0x1(%rax,%r9,1), %rax
+        imulq   %rbx
+        xorl    %ebp, %ebp
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        adcq    %r9, %r14
+        adcq    %r9, %r15
+        shlq    $0x3f, %rax
+        addq    %rax, %r15
+        cmovns  %rbp, %rbx
+        subq    %rbx, %r12
+        sbbq    %rbp, %r13
+        sbbq    %rbp, %r14
+        sbbq    %rbp, %r15
+        btr     $0x3f, %r15
+        movq    0xc0(%rsp), %rdi
+        movq    %r12, (%rdi)
+        movq    %r13, 0x8(%rdi)
+        movq    %r14, 0x10(%rdi)
+        movq    %r15, 0x18(%rdi)
+
+// The final result is x = X * inv(Z), y = Y * inv(Z).
+// These are the only operations in the whole computation that
+// fully reduce modulo p_25519 since now we want the canonical
+// answer as output.
+
+        movq    res, %rbp
+        mul_p25519(resx,x_3,w_3)
+        mul_p25519(resy,y_3,w_3)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+        CFI_RET
+
+#if WINDOWS_ABI
+S2N_BN_SIZE_DIRECTIVE(Ledwards25519_scalarmulbase_standard)
+#else
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase)
+#endif
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
+
+// ****************************************************************************
+// The precomputed data (all read-only).
+// ****************************************************************************
+
+#if defined(__ELF__)
+.section .rodata
+.type S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant), %object
+.size S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant), 48576
+#elif defined(__APPLE__)
+.const_data
+#endif
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_constant):
+
+// 0 * B = 0 and 2^251 * B in extended-projective coordinates
+// but with Z = 1 assumed and hence left out, so they are (X,Y,T) only.
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x0000000000000001
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x525f946d7c7220e7
+        .quad   0x4636b0b2f1e35444
+        .quad   0x796e9d70e892ae0f
+        .quad   0x03dec05fa937adb1
+        .quad   0x6d1c271cc6375515
+        .quad   0x462588c4a4ca4f14
+        .quad   0x691129fee55afc39
+        .quad   0x15949f784d8472f5
+        .quad   0xbd89e510afad0049
+        .quad   0x4d1f08c073b9860e
+        .quad   0x07716e8b2d00af9d
+        .quad   0x70d685f68f859714
+
+// Precomputed table of multiples of generator for edwards25519
+// all in precomputed extended-projective (y-x,x+y,2*d*x*y) triples.
+
+        // 2^0 * 1 * G
+
+        .quad   0x9d103905d740913e
+        .quad   0xfd399f05d140beb3
+        .quad   0xa5c18434688f8a09
+        .quad   0x44fd2f9298f81267
+        .quad   0x2fbc93c6f58c3b85
+        .quad   0xcf932dc6fb8c0e19
+        .quad   0x270b4898643d42c2
+        .quad   0x07cf9d3a33d4ba65
+        .quad   0xabc91205877aaa68
+        .quad   0x26d9e823ccaac49e
+        .quad   0x5a1b7dcbdd43598c
+        .quad   0x6f117b689f0c65a8
+
+        // 2^0 * 2 * G
+
+        .quad   0x8a99a56042b4d5a8
+        .quad   0x8f2b810c4e60acf6
+        .quad   0xe09e236bb16e37aa
+        .quad   0x6bb595a669c92555
+        .quad   0x9224e7fc933c71d7
+        .quad   0x9f469d967a0ff5b5
+        .quad   0x5aa69a65e1d60702
+        .quad   0x590c063fa87d2e2e
+        .quad   0x43faa8b3a59b7a5f
+        .quad   0x36c16bdd5d9acf78
+        .quad   0x500fa0840b3d6a31
+        .quad   0x701af5b13ea50b73
+
+        // 2^0 * 3 * G
+
+        .quad   0x56611fe8a4fcd265
+        .quad   0x3bd353fde5c1ba7d
+        .quad   0x8131f31a214bd6bd
+        .quad   0x2ab91587555bda62
+        .quad   0xaf25b0a84cee9730
+        .quad   0x025a8430e8864b8a
+        .quad   0xc11b50029f016732
+        .quad   0x7a164e1b9a80f8f4
+        .quad   0x14ae933f0dd0d889
+        .quad   0x589423221c35da62
+        .quad   0xd170e5458cf2db4c
+        .quad   0x5a2826af12b9b4c6
+
+        // 2^0 * 4 * G
+
+        .quad   0x95fe050a056818bf
+        .quad   0x327e89715660faa9
+        .quad   0xc3e8e3cd06a05073
+        .quad   0x27933f4c7445a49a
+        .quad   0x287351b98efc099f
+        .quad   0x6765c6f47dfd2538
+        .quad   0xca348d3dfb0a9265
+        .quad   0x680e910321e58727
+        .quad   0x5a13fbe9c476ff09
+        .quad   0x6e9e39457b5cc172
+        .quad   0x5ddbdcf9102b4494
+        .quad   0x7f9d0cbf63553e2b
+
+        // 2^0 * 5 * G
+
+        .quad   0x7f9182c3a447d6ba
+        .quad   0xd50014d14b2729b7
+        .quad   0xe33cf11cb864a087
+        .quad   0x154a7e73eb1b55f3
+        .quad   0xa212bc4408a5bb33
+        .quad   0x8d5048c3c75eed02
+        .quad   0xdd1beb0c5abfec44
+        .quad   0x2945ccf146e206eb
+        .quad   0xbcbbdbf1812a8285
+        .quad   0x270e0807d0bdd1fc
+        .quad   0xb41b670b1bbda72d
+        .quad   0x43aabe696b3bb69a
+
+        // 2^0 * 6 * G
+
+        .quad   0x499806b67b7d8ca4
+        .quad   0x575be28427d22739
+        .quad   0xbb085ce7204553b9
+        .quad   0x38b64c41ae417884
+        .quad   0x3a0ceeeb77157131
+        .quad   0x9b27158900c8af88
+        .quad   0x8065b668da59a736
+        .quad   0x51e57bb6a2cc38bd
+        .quad   0x85ac326702ea4b71
+        .quad   0xbe70e00341a1bb01
+        .quad   0x53e4a24b083bc144
+        .quad   0x10b8e91a9f0d61e3
+
+        // 2^0 * 7 * G
+
+        .quad   0xba6f2c9aaa3221b1
+        .quad   0x6ca021533bba23a7
+        .quad   0x9dea764f92192c3a
+        .quad   0x1d6edd5d2e5317e0
+        .quad   0x6b1a5cd0944ea3bf
+        .quad   0x7470353ab39dc0d2
+        .quad   0x71b2528228542e49
+        .quad   0x461bea69283c927e
+        .quad   0xf1836dc801b8b3a2
+        .quad   0xb3035f47053ea49a
+        .quad   0x529c41ba5877adf3
+        .quad   0x7a9fbb1c6a0f90a7
+
+        // 2^0 * 8 * G
+
+        .quad   0xe2a75dedf39234d9
+        .quad   0x963d7680e1b558f9
+        .quad   0x2c2741ac6e3c23fb
+        .quad   0x3a9024a1320e01c3
+        .quad   0x59b7596604dd3e8f
+        .quad   0x6cb30377e288702c
+        .quad   0xb1339c665ed9c323
+        .quad   0x0915e76061bce52f
+        .quad   0xe7c1f5d9c9a2911a
+        .quad   0xb8a371788bcca7d7
+        .quad   0x636412190eb62a32
+        .quad   0x26907c5c2ecc4e95
+
+        // 2^4 * 1 * G
+
+        .quad   0x7ec851ca553e2df3
+        .quad   0xa71284cba64878b3
+        .quad   0xe6b5e4193288d1e7
+        .quad   0x4cf210ec5a9a8883
+        .quad   0x322d04a52d9021f6
+        .quad   0xb9c19f3375c6bf9c
+        .quad   0x587a3a4342d20b09
+        .quad   0x143b1cf8aa64fe61
+        .quad   0x9f867c7d968acaab
+        .quad   0x5f54258e27092729
+        .quad   0xd0a7d34bea180975
+        .quad   0x21b546a3374126e1
+
+        // 2^4 * 2 * G
+
+        .quad   0xa94ff858a2888343
+        .quad   0xce0ed4565313ed3c
+        .quad   0xf55c3dcfb5bf34fa
+        .quad   0x0a653ca5c9eab371
+        .quad   0x490a7a45d185218f
+        .quad   0x9a15377846049335
+        .quad   0x0060ea09cc31e1f6
+        .quad   0x7e041577f86ee965
+        .quad   0x66b2a496ce5b67f3
+        .quad   0xff5492d8bd569796
+        .quad   0x503cec294a592cd0
+        .quad   0x566943650813acb2
+
+        // 2^4 * 3 * G
+
+        .quad   0xb818db0c26620798
+        .quad   0x5d5c31d9606e354a
+        .quad   0x0982fa4f00a8cdc7
+        .quad   0x17e12bcd4653e2d4
+        .quad   0x5672f9eb1dabb69d
+        .quad   0xba70b535afe853fc
+        .quad   0x47ac0f752796d66d
+        .quad   0x32a5351794117275
+        .quad   0xd3a644a6df648437
+        .quad   0x703b6559880fbfdd
+        .quad   0xcb852540ad3a1aa5
+        .quad   0x0900b3f78e4c6468
+
+        // 2^4 * 4 * G
+
+        .quad   0x0a851b9f679d651b
+        .quad   0xe108cb61033342f2
+        .quad   0xd601f57fe88b30a3
+        .quad   0x371f3acaed2dd714
+        .quad   0xed280fbec816ad31
+        .quad   0x52d9595bd8e6efe3
+        .quad   0x0fe71772f6c623f5
+        .quad   0x4314030b051e293c
+        .quad   0xd560005efbf0bcad
+        .quad   0x8eb70f2ed1870c5e
+        .quad   0x201f9033d084e6a0
+        .quad   0x4c3a5ae1ce7b6670
+
+        // 2^4 * 5 * G
+
+        .quad   0x4138a434dcb8fa95
+        .quad   0x870cf67d6c96840b
+        .quad   0xde388574297be82c
+        .quad   0x7c814db27262a55a
+        .quad   0xbaf875e4c93da0dd
+        .quad   0xb93282a771b9294d
+        .quad   0x80d63fb7f4c6c460
+        .quad   0x6de9c73dea66c181
+        .quad   0x478904d5a04df8f2
+        .quad   0xfafbae4ab10142d3
+        .quad   0xf6c8ac63555d0998
+        .quad   0x5aac4a412f90b104
+
+        // 2^4 * 6 * G
+
+        .quad   0xc64f326b3ac92908
+        .quad   0x5551b282e663e1e0
+        .quad   0x476b35f54a1a4b83
+        .quad   0x1b9da3fe189f68c2
+        .quad   0x603a0d0abd7f5134
+        .quad   0x8089c932e1d3ae46
+        .quad   0xdf2591398798bd63
+        .quad   0x1c145cd274ba0235
+        .quad   0x32e8386475f3d743
+        .quad   0x365b8baf6ae5d9ef
+        .quad   0x825238b6385b681e
+        .quad   0x234929c1167d65e1
+
+        // 2^4 * 7 * G
+
+        .quad   0x984decaba077ade8
+        .quad   0x383f77ad19eb389d
+        .quad   0xc7ec6b7e2954d794
+        .quad   0x59c77b3aeb7c3a7a
+        .quad   0x48145cc21d099fcf
+        .quad   0x4535c192cc28d7e5
+        .quad   0x80e7c1e548247e01
+        .quad   0x4a5f28743b2973ee
+        .quad   0xd3add725225ccf62
+        .quad   0x911a3381b2152c5d
+        .quad   0xd8b39fad5b08f87d
+        .quad   0x6f05606b4799fe3b
+
+        // 2^4 * 8 * G
+
+        .quad   0x9ffe9e92177ba962
+        .quad   0x98aee71d0de5cae1
+        .quad   0x3ff4ae942d831044
+        .quad   0x714de12e58533ac8
+        .quad   0x5b433149f91b6483
+        .quad   0xadb5dc655a2cbf62
+        .quad   0x87fa8412632827b3
+        .quad   0x60895e91ab49f8d8
+        .quad   0xe9ecf2ed0cf86c18
+        .quad   0xb46d06120735dfd4
+        .quad   0xbc9da09804b96be7
+        .quad   0x73e2e62fd96dc26b
+
+        // 2^8 * 1 * G
+
+        .quad   0xed5b635449aa515e
+        .quad   0xa865c49f0bc6823a
+        .quad   0x850c1fe95b42d1c4
+        .quad   0x30d76d6f03d315b9
+        .quad   0x2eccdd0e632f9c1d
+        .quad   0x51d0b69676893115
+        .quad   0x52dfb76ba8637a58
+        .quad   0x6dd37d49a00eef39
+        .quad   0x6c4444172106e4c7
+        .quad   0xfb53d680928d7f69
+        .quad   0xb4739ea4694d3f26
+        .quad   0x10c697112e864bb0
+
+        // 2^8 * 2 * G
+
+        .quad   0x6493c4277dbe5fde
+        .quad   0x265d4fad19ad7ea2
+        .quad   0x0e00dfc846304590
+        .quad   0x25e61cabed66fe09
+        .quad   0x0ca62aa08358c805
+        .quad   0x6a3d4ae37a204247
+        .quad   0x7464d3a63b11eddc
+        .quad   0x03bf9baf550806ef
+        .quad   0x3f13e128cc586604
+        .quad   0x6f5873ecb459747e
+        .quad   0xa0b63dedcc1268f5
+        .quad   0x566d78634586e22c
+
+        // 2^8 * 3 * G
+
+        .quad   0x1637a49f9cc10834
+        .quad   0xbc8e56d5a89bc451
+        .quad   0x1cb5ec0f7f7fd2db
+        .quad   0x33975bca5ecc35d9
+        .quad   0xa1054285c65a2fd0
+        .quad   0x6c64112af31667c3
+        .quad   0x680ae240731aee58
+        .quad   0x14fba5f34793b22a
+        .quad   0x3cd746166985f7d4
+        .quad   0x593e5e84c9c80057
+        .quad   0x2fc3f2b67b61131e
+        .quad   0x14829cea83fc526c
+
+        // 2^8 * 4 * G
+
+        .quad   0xff437b8497dd95c2
+        .quad   0x6c744e30aa4eb5a7
+        .quad   0x9e0c5d613c85e88b
+        .quad   0x2fd9c71e5f758173
+        .quad   0x21e70b2f4e71ecb8
+        .quad   0xe656ddb940a477e3
+        .quad   0xbf6556cece1d4f80
+        .quad   0x05fc3bc4535d7b7e
+        .quad   0x24b8b3ae52afdedd
+        .quad   0x3495638ced3b30cf
+        .quad   0x33a4bc83a9be8195
+        .quad   0x373767475c651f04
+
+        // 2^8 * 5 * G
+
+        .quad   0x2fba99fd40d1add9
+        .quad   0xb307166f96f4d027
+        .quad   0x4363f05215f03bae
+        .quad   0x1fbea56c3b18f999
+        .quad   0x634095cb14246590
+        .quad   0xef12144016c15535
+        .quad   0x9e38140c8910bc60
+        .quad   0x6bf5905730907c8c
+        .quad   0x0fa778f1e1415b8a
+        .quad   0x06409ff7bac3a77e
+        .quad   0x6f52d7b89aa29a50
+        .quad   0x02521cf67a635a56
+
+        // 2^8 * 6 * G
+
+        .quad   0x513fee0b0a9d5294
+        .quad   0x8f98e75c0fdf5a66
+        .quad   0xd4618688bfe107ce
+        .quad   0x3fa00a7e71382ced
+        .quad   0xb1146720772f5ee4
+        .quad   0xe8f894b196079ace
+        .quad   0x4af8224d00ac824a
+        .quad   0x001753d9f7cd6cc4
+        .quad   0x3c69232d963ddb34
+        .quad   0x1dde87dab4973858
+        .quad   0xaad7d1f9a091f285
+        .quad   0x12b5fe2fa048edb6
+
+        // 2^8 * 7 * G
+
+        .quad   0x71f0fbc496fce34d
+        .quad   0x73b9826badf35bed
+        .quad   0xd2047261ff28c561
+        .quad   0x749b76f96fb1206f
+        .quad   0xdf2b7c26ad6f1e92
+        .quad   0x4b66d323504b8913
+        .quad   0x8c409dc0751c8bc3
+        .quad   0x6f7e93c20796c7b8
+        .quad   0x1f5af604aea6ae05
+        .quad   0xc12351f1bee49c99
+        .quad   0x61a808b5eeff6b66
+        .quad   0x0fcec10f01e02151
+
+        // 2^8 * 8 * G
+
+        .quad   0x644d58a649fe1e44
+        .quad   0x21fcaea231ad777e
+        .quad   0x02441c5a887fd0d2
+        .quad   0x4901aa7183c511f3
+        .quad   0x3df2d29dc4244e45
+        .quad   0x2b020e7493d8de0a
+        .quad   0x6cc8067e820c214d
+        .quad   0x413779166feab90a
+        .quad   0x08b1b7548c1af8f0
+        .quad   0xce0f7a7c246299b4
+        .quad   0xf760b0f91e06d939
+        .quad   0x41bb887b726d1213
+
+        // 2^12 * 1 * G
+
+        .quad   0x9267806c567c49d8
+        .quad   0x066d04ccca791e6a
+        .quad   0xa69f5645e3cc394b
+        .quad   0x5c95b686a0788cd2
+        .quad   0x97d980e0aa39f7d2
+        .quad   0x35d0384252c6b51c
+        .quad   0x7d43f49307cd55aa
+        .quad   0x56bd36cfb78ac362
+        .quad   0x2ac519c10d14a954
+        .quad   0xeaf474b494b5fa90
+        .quad   0xe6af8382a9f87a5a
+        .quad   0x0dea6db1879be094
+
+        // 2^12 * 2 * G
+
+        .quad   0xaa66bf547344e5ab
+        .quad   0xda1258888f1b4309
+        .quad   0x5e87d2b3fd564b2f
+        .quad   0x5b2c78885483b1dd
+        .quad   0x15baeb74d6a8797a
+        .quad   0x7ef55cf1fac41732
+        .quad   0x29001f5a3c8b05c5
+        .quad   0x0ad7cc8752eaccfb
+        .quad   0x52151362793408cf
+        .quad   0xeb0f170319963d94
+        .quad   0xa833b2fa883d9466
+        .quad   0x093a7fa775003c78
+
+        // 2^12 * 3 * G
+
+        .quad   0xe5107de63a16d7be
+        .quad   0xa377ffdc9af332cf
+        .quad   0x70d5bf18440b677f
+        .quad   0x6a252b19a4a31403
+        .quad   0xb8e9604460a91286
+        .quad   0x7f3fd8047778d3de
+        .quad   0x67d01e31bf8a5e2d
+        .quad   0x7b038a06c27b653e
+        .quad   0x9ed919d5d36990f3
+        .quad   0x5213aebbdb4eb9f2
+        .quad   0xc708ea054cb99135
+        .quad   0x58ded57f72260e56
+
+        // 2^12 * 4 * G
+
+        .quad   0x78e79dade9413d77
+        .quad   0xf257f9d59729e67d
+        .quad   0x59db910ee37aa7e6
+        .quad   0x6aa11b5bbb9e039c
+        .quad   0xda6d53265b0fd48b
+        .quad   0x8960823193bfa988
+        .quad   0xd78ac93261d57e28
+        .quad   0x79f2942d3a5c8143
+        .quad   0x97da2f25b6c88de9
+        .quad   0x251ba7eaacf20169
+        .quad   0x09b44f87ef4eb4e4
+        .quad   0x7d90ab1bbc6a7da5
+
+        // 2^12 * 5 * G
+
+        .quad   0x9acca683a7016bfe
+        .quad   0x90505f4df2c50b6d
+        .quad   0x6b610d5fcce435aa
+        .quad   0x19a10d446198ff96
+        .quad   0x1a07a3f496b3c397
+        .quad   0x11ceaa188f4e2532
+        .quad   0x7d9498d5a7751bf0
+        .quad   0x19ed161f508dd8a0
+        .quad   0x560a2cd687dce6ca
+        .quad   0x7f3568c48664cf4d
+        .quad   0x8741e95222803a38
+        .quad   0x483bdab1595653fc
+
+        // 2^12 * 6 * G
+
+        .quad   0xfa780f148734fa49
+        .quad   0x106f0b70360534e0
+        .quad   0x2210776fe3e307bd
+        .quad   0x3286c109dde6a0fe
+        .quad   0xd6cf4d0ab4da80f6
+        .quad   0x82483e45f8307fe0
+        .quad   0x05005269ae6f9da4
+        .quad   0x1c7052909cf7877a
+        .quad   0x32ee7de2874e98d4
+        .quad   0x14c362e9b97e0c60
+        .quad   0x5781dcde6a60a38a
+        .quad   0x217dd5eaaa7aa840
+
+        // 2^12 * 7 * G
+
+        .quad   0x9db7c4d0248e1eb0
+        .quad   0xe07697e14d74bf52
+        .quad   0x1e6a9b173c562354
+        .quad   0x7fa7c21f795a4965
+        .quad   0x8bdf1fb9be8c0ec8
+        .quad   0x00bae7f8e30a0282
+        .quad   0x4963991dad6c4f6c
+        .quad   0x07058a6e5df6f60a
+        .quad   0xe9eb02c4db31f67f
+        .quad   0xed25fd8910bcfb2b
+        .quad   0x46c8131f5c5cddb4
+        .quad   0x33b21c13a0cb9bce
+
+        // 2^12 * 8 * G
+
+        .quad   0x360692f8087d8e31
+        .quad   0xf4dcc637d27163f7
+        .quad   0x25a4e62065ea5963
+        .quad   0x659bf72e5ac160d9
+        .quad   0x9aafb9b05ee38c5b
+        .quad   0xbf9d2d4e071a13c7
+        .quad   0x8eee6e6de933290a
+        .quad   0x1c3bab17ae109717
+        .quad   0x1c9ab216c7cab7b0
+        .quad   0x7d65d37407bbc3cc
+        .quad   0x52744750504a58d5
+        .quad   0x09f2606b131a2990
+
+        // 2^16 * 1 * G
+
+        .quad   0x40e87d44744346be
+        .quad   0x1d48dad415b52b25
+        .quad   0x7c3a8a18a13b603e
+        .quad   0x4eb728c12fcdbdf7
+        .quad   0x7e234c597c6691ae
+        .quad   0x64889d3d0a85b4c8
+        .quad   0xdae2c90c354afae7
+        .quad   0x0a871e070c6a9e1d
+        .quad   0x3301b5994bbc8989
+        .quad   0x736bae3a5bdd4260
+        .quad   0x0d61ade219d59e3c
+        .quad   0x3ee7300f2685d464
+
+        // 2^16 * 2 * G
+
+        .quad   0xf5d255e49e7dd6b7
+        .quad   0x8016115c610b1eac
+        .quad   0x3c99975d92e187ca
+        .quad   0x13815762979125c2
+        .quad   0x43fa7947841e7518
+        .quad   0xe5c6fa59639c46d7
+        .quad   0xa1065e1de3052b74
+        .quad   0x7d47c6a2cfb89030
+        .quad   0x3fdad0148ef0d6e0
+        .quad   0x9d3e749a91546f3c
+        .quad   0x71ec621026bb8157
+        .quad   0x148cf58d34c9ec80
+
+        // 2^16 * 3 * G
+
+        .quad   0x46a492f67934f027
+        .quad   0x469984bef6840aa9
+        .quad   0x5ca1bc2a89611854
+        .quad   0x3ff2fa1ebd5dbbd4
+        .quad   0xe2572f7d9ae4756d
+        .quad   0x56c345bb88f3487f
+        .quad   0x9fd10b6d6960a88d
+        .quad   0x278febad4eaea1b9
+        .quad   0xb1aa681f8c933966
+        .quad   0x8c21949c20290c98
+        .quad   0x39115291219d3c52
+        .quad   0x4104dd02fe9c677b
+
+        // 2^16 * 4 * G
+
+        .quad   0x72b2bf5e1124422a
+        .quad   0xa1fa0c3398a33ab5
+        .quad   0x94cb6101fa52b666
+        .quad   0x2c863b00afaf53d5
+        .quad   0x81214e06db096ab8
+        .quad   0x21a8b6c90ce44f35
+        .quad   0x6524c12a409e2af5
+        .quad   0x0165b5a48efca481
+        .quad   0xf190a474a0846a76
+        .quad   0x12eff984cd2f7cc0
+        .quad   0x695e290658aa2b8f
+        .quad   0x591b67d9bffec8b8
+
+        // 2^16 * 5 * G
+
+        .quad   0x312f0d1c80b49bfa
+        .quad   0x5979515eabf3ec8a
+        .quad   0x727033c09ef01c88
+        .quad   0x3de02ec7ca8f7bcb
+        .quad   0x99b9b3719f18b55d
+        .quad   0xe465e5faa18c641e
+        .quad   0x61081136c29f05ed
+        .quad   0x489b4f867030128b
+        .quad   0xd232102d3aeb92ef
+        .quad   0xe16253b46116a861
+        .quad   0x3d7eabe7190baa24
+        .quad   0x49f5fbba496cbebf
+
+        // 2^16 * 6 * G
+
+        .quad   0x30949a108a5bcfd4
+        .quad   0xdc40dd70bc6473eb
+        .quad   0x92c294c1307c0d1c
+        .quad   0x5604a86dcbfa6e74
+        .quad   0x155d628c1e9c572e
+        .quad   0x8a4d86acc5884741
+        .quad   0x91a352f6515763eb
+        .quad   0x06a1a6c28867515b
+        .quad   0x7288d1d47c1764b6
+        .quad   0x72541140e0418b51
+        .quad   0x9f031a6018acf6d1
+        .quad   0x20989e89fe2742c6
+
+        // 2^16 * 7 * G
+
+        .quad   0x499777fd3a2dcc7f
+        .quad   0x32857c2ca54fd892
+        .quad   0xa279d864d207e3a0
+        .quad   0x0403ed1d0ca67e29
+        .quad   0x1674278b85eaec2e
+        .quad   0x5621dc077acb2bdf
+        .quad   0x640a4c1661cbf45a
+        .quad   0x730b9950f70595d3
+        .quad   0xc94b2d35874ec552
+        .quad   0xc5e6c8cf98246f8d
+        .quad   0xf7cb46fa16c035ce
+        .quad   0x5bd7454308303dcc
+
+        // 2^16 * 8 * G
+
+        .quad   0x7f9ad19528b24cc2
+        .quad   0x7f6b54656335c181
+        .quad   0x66b8b66e4fc07236
+        .quad   0x133a78007380ad83
+        .quad   0x85c4932115e7792a
+        .quad   0xc64c89a2bdcdddc9
+        .quad   0x9d1e3da8ada3d762
+        .quad   0x5bb7db123067f82c
+        .quad   0x0961f467c6ca62be
+        .quad   0x04ec21d6211952ee
+        .quad   0x182360779bd54770
+        .quad   0x740dca6d58f0e0d2
+
+        // 2^20 * 1 * G
+
+        .quad   0x50b70bf5d3f0af0b
+        .quad   0x4feaf48ae32e71f7
+        .quad   0x60e84ed3a55bbd34
+        .quad   0x00ed489b3f50d1ed
+        .quad   0x3906c72aed261ae5
+        .quad   0x9ab68fd988e100f7
+        .quad   0xf5e9059af3360197
+        .quad   0x0e53dc78bf2b6d47
+        .quad   0xb90829bf7971877a
+        .quad   0x5e4444636d17e631
+        .quad   0x4d05c52e18276893
+        .quad   0x27632d9a5a4a4af5
+
+        // 2^20 * 2 * G
+
+        .quad   0xd11ff05154b260ce
+        .quad   0xd86dc38e72f95270
+        .quad   0x601fcd0d267cc138
+        .quad   0x2b67916429e90ccd
+        .quad   0xa98285d187eaffdb
+        .quad   0xa5b4fbbbd8d0a864
+        .quad   0xb658f27f022663f7
+        .quad   0x3bbc2b22d99ce282
+        .quad   0xb917c952583c0a58
+        .quad   0x653ff9b80fe4c6f3
+        .quad   0x9b0da7d7bcdf3c0c
+        .quad   0x43a0eeb6ab54d60e
+
+        // 2^20 * 3 * G
+
+        .quad   0x396966a46d4a5487
+        .quad   0xf811a18aac2bb3ba
+        .quad   0x66e4685b5628b26b
+        .quad   0x70a477029d929b92
+        .quad   0x3ac6322357875fe8
+        .quad   0xd9d4f4ecf5fbcb8f
+        .quad   0x8dee8493382bb620
+        .quad   0x50c5eaa14c799fdc
+        .quad   0xdd0edc8bd6f2fb3c
+        .quad   0x54c63aa79cc7b7a0
+        .quad   0xae0b032b2c8d9f1a
+        .quad   0x6f9ce107602967fb
+
+        // 2^20 * 4 * G
+
+        .quad   0xad1054b1cde1c22a
+        .quad   0xc4a8e90248eb32df
+        .quad   0x5f3e7b33accdc0ea
+        .quad   0x72364713fc79963e
+        .quad   0x139693063520e0b5
+        .quad   0x437fcf7c88ea03fe
+        .quad   0xf7d4c40bd3c959bc
+        .quad   0x699154d1f893ded9
+        .quad   0x315d5c75b4b27526
+        .quad   0xcccb842d0236daa5
+        .quad   0x22f0c8a3345fee8e
+        .quad   0x73975a617d39dbed
+
+        // 2^20 * 5 * G
+
+        .quad   0xe4024df96375da10
+        .quad   0x78d3251a1830c870
+        .quad   0x902b1948658cd91c
+        .quad   0x7e18b10b29b7438a
+        .quad   0x6f37f392f4433e46
+        .quad   0x0e19b9a11f566b18
+        .quad   0x220fb78a1fd1d662
+        .quad   0x362a4258a381c94d
+        .quad   0x9071d9132b6beb2f
+        .quad   0x0f26e9ad28418247
+        .quad   0xeab91ec9bdec925d
+        .quad   0x4be65bc8f48af2de
+
+        // 2^20 * 6 * G
+
+        .quad   0x78487feba36e7028
+        .quad   0x5f3f13001dd8ce34
+        .quad   0x934fb12d4b30c489
+        .quad   0x056c244d397f0a2b
+        .quad   0x1d50fba257c26234
+        .quad   0x7bd4823adeb0678b
+        .quad   0xc2b0dc6ea6538af5
+        .quad   0x5665eec6351da73e
+        .quad   0xdb3ee00943bfb210
+        .quad   0x4972018720800ac2
+        .quad   0x26ab5d6173bd8667
+        .quad   0x20b209c2ab204938
+
+        // 2^20 * 7 * G
+
+        .quad   0x549e342ac07fb34b
+        .quad   0x02d8220821373d93
+        .quad   0xbc262d70acd1f567
+        .quad   0x7a92c9fdfbcac784
+        .quad   0x1fcca94516bd3289
+        .quad   0x448d65aa41420428
+        .quad   0x59c3b7b216a55d62
+        .quad   0x49992cc64e612cd8
+        .quad   0x65bd1bea70f801de
+        .quad   0x1befb7c0fe49e28a
+        .quad   0xa86306cdb1b2ae4a
+        .quad   0x3b7ac0cd265c2a09
+
+        // 2^20 * 8 * G
+
+        .quad   0x822bee438c01bcec
+        .quad   0x530cb525c0fbc73b
+        .quad   0x48519034c1953fe9
+        .quad   0x265cc261e09a0f5b
+        .quad   0xf0d54e4f22ed39a7
+        .quad   0xa2aae91e5608150a
+        .quad   0xf421b2e9eddae875
+        .quad   0x31bc531d6b7de992
+        .quad   0xdf3d134da980f971
+        .quad   0x7a4fb8d1221a22a7
+        .quad   0x3df7d42035aad6d8
+        .quad   0x2a14edcc6a1a125e
+
+        // 2^24 * 1 * G
+
+        .quad   0xdf48ee0752cfce4e
+        .quad   0xc3fffaf306ec08b7
+        .quad   0x05710b2ab95459c4
+        .quad   0x161d25fa963ea38d
+        .quad   0x231a8c570478433c
+        .quad   0xb7b5270ec281439d
+        .quad   0xdbaa99eae3d9079f
+        .quad   0x2c03f5256c2b03d9
+        .quad   0x790f18757b53a47d
+        .quad   0x307b0130cf0c5879
+        .quad   0x31903d77257ef7f9
+        .quad   0x699468bdbd96bbaf
+
+        // 2^24 * 2 * G
+
+        .quad   0xbd1f2f46f4dafecf
+        .quad   0x7cef0114a47fd6f7
+        .quad   0xd31ffdda4a47b37f
+        .quad   0x525219a473905785
+        .quad   0xd8dd3de66aa91948
+        .quad   0x485064c22fc0d2cc
+        .quad   0x9b48246634fdea2f
+        .quad   0x293e1c4e6c4a2e3a
+        .quad   0x376e134b925112e1
+        .quad   0x703778b5dca15da0
+        .quad   0xb04589af461c3111
+        .quad   0x5b605c447f032823
+
+        // 2^24 * 3 * G
+
+        .quad   0xb965805920c47c89
+        .quad   0xe7f0100c923b8fcc
+        .quad   0x0001256502e2ef77
+        .quad   0x24a76dcea8aeb3ee
+        .quad   0x3be9fec6f0e7f04c
+        .quad   0x866a579e75e34962
+        .quad   0x5542ef161e1de61a
+        .quad   0x2f12fef4cc5abdd5
+        .quad   0x0a4522b2dfc0c740
+        .quad   0x10d06e7f40c9a407
+        .quad   0xc6cf144178cff668
+        .quad   0x5e607b2518a43790
+
+        // 2^24 * 4 * G
+
+        .quad   0x58b31d8f6cdf1818
+        .quad   0x35cfa74fc36258a2
+        .quad   0xe1b3ff4f66e61d6e
+        .quad   0x5067acab6ccdd5f7
+        .quad   0xa02c431ca596cf14
+        .quad   0xe3c42d40aed3e400
+        .quad   0xd24526802e0f26db
+        .quad   0x201f33139e457068
+        .quad   0xfd527f6b08039d51
+        .quad   0x18b14964017c0006
+        .quad   0xd5220eb02e25a4a8
+        .quad   0x397cba8862460375
+
+        // 2^24 * 5 * G
+
+        .quad   0x30c13093f05959b2
+        .quad   0xe23aa18de9a97976
+        .quad   0x222fd491721d5e26
+        .quad   0x2339d320766e6c3a
+        .quad   0x7815c3fbc81379e7
+        .quad   0xa6619420dde12af1
+        .quad   0xffa9c0f885a8fdd5
+        .quad   0x771b4022c1e1c252
+        .quad   0xd87dd986513a2fa7
+        .quad   0xf5ac9b71f9d4cf08
+        .quad   0xd06bc31b1ea283b3
+        .quad   0x331a189219971a76
+
+        // 2^24 * 6 * G
+
+        .quad   0xf5166f45fb4f80c6
+        .quad   0x9c36c7de61c775cf
+        .quad   0xe3d4e81b9041d91c
+        .quad   0x31167c6b83bdfe21
+        .quad   0x26512f3a9d7572af
+        .quad   0x5bcbe28868074a9e
+        .quad   0x84edc1c11180f7c4
+        .quad   0x1ac9619ff649a67b
+        .quad   0xf22b3842524b1068
+        .quad   0x5068343bee9ce987
+        .quad   0xfc9d71844a6250c8
+        .quad   0x612436341f08b111
+
+        // 2^24 * 7 * G
+
+        .quad   0xd99d41db874e898d
+        .quad   0x09fea5f16c07dc20
+        .quad   0x793d2c67d00f9bbc
+        .quad   0x46ebe2309e5eff40
+        .quad   0x8b6349e31a2d2638
+        .quad   0x9ddfb7009bd3fd35
+        .quad   0x7f8bf1b8a3a06ba4
+        .quad   0x1522aa3178d90445
+        .quad   0x2c382f5369614938
+        .quad   0xdafe409ab72d6d10
+        .quad   0xe8c83391b646f227
+        .quad   0x45fe70f50524306c
+
+        // 2^24 * 8 * G
+
+        .quad   0xda4875a6960c0b8c
+        .quad   0x5b68d076ef0e2f20
+        .quad   0x07fb51cf3d0b8fd4
+        .quad   0x428d1623a0e392d4
+        .quad   0x62f24920c8951491
+        .quad   0x05f007c83f630ca2
+        .quad   0x6fbb45d2f5c9d4b8
+        .quad   0x16619f6db57a2245
+        .quad   0x084f4a4401a308fd
+        .quad   0xa82219c376a5caac
+        .quad   0xdeb8de4643d1bc7d
+        .quad   0x1d81592d60bd38c6
+
+        // 2^28 * 1 * G
+
+        .quad   0xd833d7beec2a4c38
+        .quad   0x2c9162830acc20ed
+        .quad   0xe93a47aa92df7581
+        .quad   0x702d67a3333c4a81
+        .quad   0x3a4a369a2f89c8a1
+        .quad   0x63137a1d7c8de80d
+        .quad   0xbcac008a78eda015
+        .quad   0x2cb8b3a5b483b03f
+        .quad   0x36e417cbcb1b90a1
+        .quad   0x33b3ddaa7f11794e
+        .quad   0x3f510808885bc607
+        .quad   0x24141dc0e6a8020d
+
+        // 2^28 * 2 * G
+
+        .quad   0x59f73c773fefee9d
+        .quad   0xb3f1ef89c1cf989d
+        .quad   0xe35dfb42e02e545f
+        .quad   0x5766120b47a1b47c
+        .quad   0x91925dccbd83157d
+        .quad   0x3ca1205322cc8094
+        .quad   0x28e57f183f90d6e4
+        .quad   0x1a4714cede2e767b
+        .quad   0xdb20ba0fb8b6b7ff
+        .quad   0xb732c3b677511fa1
+        .quad   0xa92b51c099f02d89
+        .quad   0x4f3875ad489ca5f1
+
+        // 2^28 * 3 * G
+
+        .quad   0xc7fc762f4932ab22
+        .quad   0x7ac0edf72f4c3c1b
+        .quad   0x5f6b55aa9aa895e8
+        .quad   0x3680274dad0a0081
+        .quad   0x79ed13f6ee73eec0
+        .quad   0xa5c6526d69110bb1
+        .quad   0xe48928c38603860c
+        .quad   0x722a1446fd7059f5
+        .quad   0xd0959fe9a8cf8819
+        .quad   0xd0a995508475a99c
+        .quad   0x6eac173320b09cc5
+        .quad   0x628ecf04331b1095
+
+        // 2^28 * 4 * G
+
+        .quad   0x98bcb118a9d0ddbc
+        .quad   0xee449e3408b4802b
+        .quad   0x87089226b8a6b104
+        .quad   0x685f349a45c7915d
+        .quad   0x9b41acf85c74ccf1
+        .quad   0xb673318108265251
+        .quad   0x99c92aed11adb147
+        .quad   0x7a47d70d34ecb40f
+        .quad   0x60a0c4cbcc43a4f5
+        .quad   0x775c66ca3677bea9
+        .quad   0xa17aa1752ff8f5ed
+        .quad   0x11ded9020e01fdc0
+
+        // 2^28 * 5 * G
+
+        .quad   0x890e7809caefe704
+        .quad   0x8728296de30e8c6c
+        .quad   0x4c5cd2a392aeb1c9
+        .quad   0x194263d15771531f
+        .quad   0x471f95b03bea93b7
+        .quad   0x0552d7d43313abd3
+        .quad   0xbd9370e2e17e3f7b
+        .quad   0x7b120f1db20e5bec
+        .quad   0x17d2fb3d86502d7a
+        .quad   0xb564d84450a69352
+        .quad   0x7da962c8a60ed75d
+        .quad   0x00d0f85b318736aa
+
+        // 2^28 * 6 * G
+
+        .quad   0x978b142e777c84fd
+        .quad   0xf402644705a8c062
+        .quad   0xa67ad51be7e612c7
+        .quad   0x2f7b459698dd6a33
+        .quad   0xa6753c1efd7621c1
+        .quad   0x69c0b4a7445671f5
+        .quad   0x971f527405b23c11
+        .quad   0x387bc74851a8c7cd
+        .quad   0x81894b4d4a52a9a8
+        .quad   0xadd93e12f6b8832f
+        .quad   0x184d8548b61bd638
+        .quad   0x3f1c62dbd6c9f6cd
+
+        // 2^28 * 7 * G
+
+        .quad   0x2e8f1f0091910c1f
+        .quad   0xa4df4fe0bff2e12c
+        .quad   0x60c6560aee927438
+        .quad   0x6338283facefc8fa
+        .quad   0x3fad3e40148f693d
+        .quad   0x052656e194eb9a72
+        .quad   0x2f4dcbfd184f4e2f
+        .quad   0x406f8db1c482e18b
+        .quad   0x9e630d2c7f191ee4
+        .quad   0x4fbf8301bc3ff670
+        .quad   0x787d8e4e7afb73c4
+        .quad   0x50d83d5be8f58fa5
+
+        // 2^28 * 8 * G
+
+        .quad   0x85683916c11a1897
+        .quad   0x2d69a4efe506d008
+        .quad   0x39af1378f664bd01
+        .quad   0x65942131361517c6
+        .quad   0xc0accf90b4d3b66d
+        .quad   0xa7059de561732e60
+        .quad   0x033d1f7870c6b0ba
+        .quad   0x584161cd26d946e4
+        .quad   0xbbf2b1a072d27ca2
+        .quad   0xbf393c59fbdec704
+        .quad   0xe98dbbcee262b81e
+        .quad   0x02eebd0b3029b589
+
+        // 2^32 * 1 * G
+
+        .quad   0x61368756a60dac5f
+        .quad   0x17e02f6aebabdc57
+        .quad   0x7f193f2d4cce0f7d
+        .quad   0x20234a7789ecdcf0
+        .quad   0x8765b69f7b85c5e8
+        .quad   0x6ff0678bd168bab2
+        .quad   0x3a70e77c1d330f9b
+        .quad   0x3a5f6d51b0af8e7c
+        .quad   0x76d20db67178b252
+        .quad   0x071c34f9d51ed160
+        .quad   0xf62a4a20b3e41170
+        .quad   0x7cd682353cffe366
+
+        // 2^32 * 2 * G
+
+        .quad   0x0be1a45bd887fab6
+        .quad   0x2a846a32ba403b6e
+        .quad   0xd9921012e96e6000
+        .quad   0x2838c8863bdc0943
+        .quad   0xa665cd6068acf4f3
+        .quad   0x42d92d183cd7e3d3
+        .quad   0x5759389d336025d9
+        .quad   0x3ef0253b2b2cd8ff
+        .quad   0xd16bb0cf4a465030
+        .quad   0xfa496b4115c577ab
+        .quad   0x82cfae8af4ab419d
+        .quad   0x21dcb8a606a82812
+
+        // 2^32 * 3 * G
+
+        .quad   0x5c6004468c9d9fc8
+        .quad   0x2540096ed42aa3cb
+        .quad   0x125b4d4c12ee2f9c
+        .quad   0x0bc3d08194a31dab
+        .quad   0x9a8d00fabe7731ba
+        .quad   0x8203607e629e1889
+        .quad   0xb2cc023743f3d97f
+        .quad   0x5d840dbf6c6f678b
+        .quad   0x706e380d309fe18b
+        .quad   0x6eb02da6b9e165c7
+        .quad   0x57bbba997dae20ab
+        .quad   0x3a4276232ac196dd
+
+        // 2^32 * 4 * G
+
+        .quad   0x4b42432c8a7084fa
+        .quad   0x898a19e3dfb9e545
+        .quad   0xbe9f00219c58e45d
+        .quad   0x1ff177cea16debd1
+        .quad   0x3bf8c172db447ecb
+        .quad   0x5fcfc41fc6282dbd
+        .quad   0x80acffc075aa15fe
+        .quad   0x0770c9e824e1a9f9
+        .quad   0xcf61d99a45b5b5fd
+        .quad   0x860984e91b3a7924
+        .quad   0xe7300919303e3e89
+        .quad   0x39f264fd41500b1e
+
+        // 2^32 * 5 * G
+
+        .quad   0xa7ad3417dbe7e29c
+        .quad   0xbd94376a2b9c139c
+        .quad   0xa0e91b8e93597ba9
+        .quad   0x1712d73468889840
+        .quad   0xd19b4aabfe097be1
+        .quad   0xa46dfce1dfe01929
+        .quad   0xc3c908942ca6f1ff
+        .quad   0x65c621272c35f14e
+        .quad   0xe72b89f8ce3193dd
+        .quad   0x4d103356a125c0bb
+        .quad   0x0419a93d2e1cfe83
+        .quad   0x22f9800ab19ce272
+
+        // 2^32 * 6 * G
+
+        .quad   0x605a368a3e9ef8cb
+        .quad   0xe3e9c022a5504715
+        .quad   0x553d48b05f24248f
+        .quad   0x13f416cd647626e5
+        .quad   0x42029fdd9a6efdac
+        .quad   0xb912cebe34a54941
+        .quad   0x640f64b987bdf37b
+        .quad   0x4171a4d38598cab4
+        .quad   0xfa2758aa99c94c8c
+        .quad   0x23006f6fb000b807
+        .quad   0xfbd291ddadda5392
+        .quad   0x508214fa574bd1ab
+
+        // 2^32 * 7 * G
+
+        .quad   0xc20269153ed6fe4b
+        .quad   0xa65a6739511d77c4
+        .quad   0xcbde26462c14af94
+        .quad   0x22f960ec6faba74b
+        .quad   0x461a15bb53d003d6
+        .quad   0xb2102888bcf3c965
+        .quad   0x27c576756c683a5a
+        .quad   0x3a7758a4c86cb447
+        .quad   0x548111f693ae5076
+        .quad   0x1dae21df1dfd54a6
+        .quad   0x12248c90f3115e65
+        .quad   0x5d9fd15f8de7f494
+
+        // 2^32 * 8 * G
+
+        .quad   0x031408d36d63727f
+        .quad   0x6a379aefd7c7b533
+        .quad   0xa9e18fc5ccaee24b
+        .quad   0x332f35914f8fbed3
+        .quad   0x3f244d2aeed7521e
+        .quad   0x8e3a9028432e9615
+        .quad   0xe164ba772e9c16d4
+        .quad   0x3bc187fa47eb98d8
+        .quad   0x6d470115ea86c20c
+        .quad   0x998ab7cb6c46d125
+        .quad   0xd77832b53a660188
+        .quad   0x450d81ce906fba03
+
+        // 2^36 * 1 * G
+
+        .quad   0xf8ae4d2ad8453902
+        .quad   0x7018058ee8db2d1d
+        .quad   0xaab3995fc7d2c11e
+        .quad   0x53b16d2324ccca79
+        .quad   0x23264d66b2cae0b5
+        .quad   0x7dbaed33ebca6576
+        .quad   0x030ebed6f0d24ac8
+        .quad   0x2a887f78f7635510
+        .quad   0x2a23b9e75c012d4f
+        .quad   0x0c974651cae1f2ea
+        .quad   0x2fb63273675d70ca
+        .quad   0x0ba7250b864403f5
+
+        // 2^36 * 2 * G
+
+        .quad   0xbb0d18fd029c6421
+        .quad   0xbc2d142189298f02
+        .quad   0x8347f8e68b250e96
+        .quad   0x7b9f2fe8032d71c9
+        .quad   0xdd63589386f86d9c
+        .quad   0x61699176e13a85a4
+        .quad   0x2e5111954eaa7d57
+        .quad   0x32c21b57fb60bdfb
+        .quad   0xd87823cd319e0780
+        .quad   0xefc4cfc1897775c5
+        .quad   0x4854fb129a0ab3f7
+        .quad   0x12c49d417238c371
+
+        // 2^36 * 3 * G
+
+        .quad   0x0950b533ffe83769
+        .quad   0x21861c1d8e1d6bd1
+        .quad   0xf022d8381302e510
+        .quad   0x2509200c6391cab4
+        .quad   0x09b3a01783799542
+        .quad   0x626dd08faad5ee3f
+        .quad   0xba00bceeeb70149f
+        .quad   0x1421b246a0a444c9
+        .quad   0x4aa43a8e8c24a7c7
+        .quad   0x04c1f540d8f05ef5
+        .quad   0xadba5e0c0b3eb9dc
+        .quad   0x2ab5504448a49ce3
+
+        // 2^36 * 4 * G
+
+        .quad   0x2ed227266f0f5dec
+        .quad   0x9824ee415ed50824
+        .quad   0x807bec7c9468d415
+        .quad   0x7093bae1b521e23f
+        .quad   0xdc07ac631c5d3afa
+        .quad   0x58615171f9df8c6c
+        .quad   0x72a079d89d73e2b0
+        .quad   0x7301f4ceb4eae15d
+        .quad   0x6409e759d6722c41
+        .quad   0xa674e1cf72bf729b
+        .quad   0xbc0a24eb3c21e569
+        .quad   0x390167d24ebacb23
+
+        // 2^36 * 5 * G
+
+        .quad   0x27f58e3bba353f1c
+        .quad   0x4c47764dbf6a4361
+        .quad   0xafbbc4e56e562650
+        .quad   0x07db2ee6aae1a45d
+        .quad   0xd7bb054ba2f2120b
+        .quad   0xe2b9ceaeb10589b7
+        .quad   0x3fe8bac8f3c0edbe
+        .quad   0x4cbd40767112cb69
+        .quad   0x0b603cc029c58176
+        .quad   0x5988e3825cb15d61
+        .quad   0x2bb61413dcf0ad8d
+        .quad   0x7b8eec6c74183287
+
+        // 2^36 * 6 * G
+
+        .quad   0xe4ca40782cd27cb0
+        .quad   0xdaf9c323fbe967bd
+        .quad   0xb29bd34a8ad41e9e
+        .quad   0x72810497626ede4d
+        .quad   0x32fee570fc386b73
+        .quad   0xda8b0141da3a8cc7
+        .quad   0x975ffd0ac8968359
+        .quad   0x6ee809a1b132a855
+        .quad   0x9444bb31fcfd863a
+        .quad   0x2fe3690a3e4e48c5
+        .quad   0xdc29c867d088fa25
+        .quad   0x13bd1e38d173292e
+
+        // 2^36 * 7 * G
+
+        .quad   0xd32b4cd8696149b5
+        .quad   0xe55937d781d8aab7
+        .quad   0x0bcb2127ae122b94
+        .quad   0x41e86fcfb14099b0
+        .quad   0x223fb5cf1dfac521
+        .quad   0x325c25316f554450
+        .quad   0x030b98d7659177ac
+        .quad   0x1ed018b64f88a4bd
+        .quad   0x3630dfa1b802a6b0
+        .quad   0x880f874742ad3bd5
+        .quad   0x0af90d6ceec5a4d4
+        .quad   0x746a247a37cdc5d9
+
+        // 2^36 * 8 * G
+
+        .quad   0xd531b8bd2b7b9af6
+        .quad   0x5005093537fc5b51
+        .quad   0x232fcf25c593546d
+        .quad   0x20a365142bb40f49
+        .quad   0x6eccd85278d941ed
+        .quad   0x2254ae83d22f7843
+        .quad   0xc522d02e7bbfcdb7
+        .quad   0x681e3351bff0e4e2
+        .quad   0x8b64b59d83034f45
+        .quad   0x2f8b71f21fa20efb
+        .quad   0x69249495ba6550e4
+        .quad   0x539ef98e45d5472b
+
+        // 2^40 * 1 * G
+
+        .quad   0x6e7bb6a1a6205275
+        .quad   0xaa4f21d7413c8e83
+        .quad   0x6f56d155e88f5cb2
+        .quad   0x2de25d4ba6345be1
+        .quad   0xd074d8961cae743f
+        .quad   0xf86d18f5ee1c63ed
+        .quad   0x97bdc55be7f4ed29
+        .quad   0x4cbad279663ab108
+        .quad   0x80d19024a0d71fcd
+        .quad   0xc525c20afb288af8
+        .quad   0xb1a3974b5f3a6419
+        .quad   0x7d7fbcefe2007233
+
+        // 2^40 * 2 * G
+
+        .quad   0xfaef1e6a266b2801
+        .quad   0x866c68c4d5739f16
+        .quad   0xf68a2fbc1b03762c
+        .quad   0x5975435e87b75a8d
+        .quad   0xcd7c5dc5f3c29094
+        .quad   0xc781a29a2a9105ab
+        .quad   0x80c61d36421c3058
+        .quad   0x4f9cd196dcd8d4d7
+        .quad   0x199297d86a7b3768
+        .quad   0xd0d058241ad17a63
+        .quad   0xba029cad5c1c0c17
+        .quad   0x7ccdd084387a0307
+
+        // 2^40 * 3 * G
+
+        .quad   0xdca6422c6d260417
+        .quad   0xae153d50948240bd
+        .quad   0xa9c0c1b4fb68c677
+        .quad   0x428bd0ed61d0cf53
+        .quad   0x9b0c84186760cc93
+        .quad   0xcdae007a1ab32a99
+        .quad   0xa88dec86620bda18
+        .quad   0x3593ca848190ca44
+        .quad   0x9213189a5e849aa7
+        .quad   0xd4d8c33565d8facd
+        .quad   0x8c52545b53fdbbd1
+        .quad   0x27398308da2d63e6
+
+        // 2^40 * 4 * G
+
+        .quad   0x42c38d28435ed413
+        .quad   0xbd50f3603278ccc9
+        .quad   0xbb07ab1a79da03ef
+        .quad   0x269597aebe8c3355
+        .quad   0xb9a10e4c0a702453
+        .quad   0x0fa25866d57d1bde
+        .quad   0xffb9d9b5cd27daf7
+        .quad   0x572c2945492c33fd
+        .quad   0xc77fc745d6cd30be
+        .quad   0xe4dfe8d3e3baaefb
+        .quad   0xa22c8830aa5dda0c
+        .quad   0x7f985498c05bca80
+
+        // 2^40 * 5 * G
+
+        .quad   0x3849ce889f0be117
+        .quad   0x8005ad1b7b54a288
+        .quad   0x3da3c39f23fc921c
+        .quad   0x76c2ec470a31f304
+        .quad   0xd35615520fbf6363
+        .quad   0x08045a45cf4dfba6
+        .quad   0xeec24fbc873fa0c2
+        .quad   0x30f2653cd69b12e7
+        .quad   0x8a08c938aac10c85
+        .quad   0x46179b60db276bcb
+        .quad   0xa920c01e0e6fac70
+        .quad   0x2f1273f1596473da
+
+        // 2^40 * 6 * G
+
+        .quad   0x4739fc7c8ae01e11
+        .quad   0xfd5274904a6aab9f
+        .quad   0x41d98a8287728f2e
+        .quad   0x5d9e572ad85b69f2
+        .quad   0x30488bd755a70bc0
+        .quad   0x06d6b5a4f1d442e7
+        .quad   0xead1a69ebc596162
+        .quad   0x38ac1997edc5f784
+        .quad   0x0666b517a751b13b
+        .quad   0x747d06867e9b858c
+        .quad   0xacacc011454dde49
+        .quad   0x22dfcd9cbfe9e69c
+
+        // 2^40 * 7 * G
+
+        .quad   0x8ddbd2e0c30d0cd9
+        .quad   0xad8e665facbb4333
+        .quad   0x8f6b258c322a961f
+        .quad   0x6b2916c05448c1c7
+        .quad   0x56ec59b4103be0a1
+        .quad   0x2ee3baecd259f969
+        .quad   0x797cb29413f5cd32
+        .quad   0x0fe9877824cde472
+        .quad   0x7edb34d10aba913b
+        .quad   0x4ea3cd822e6dac0e
+        .quad   0x66083dff6578f815
+        .quad   0x4c303f307ff00a17
+
+        // 2^40 * 8 * G
+
+        .quad   0xd30a3bd617b28c85
+        .quad   0xc5d377b739773bea
+        .quad   0xc6c6e78c1e6a5cbf
+        .quad   0x0d61b8f78b2ab7c4
+        .quad   0x29fc03580dd94500
+        .quad   0xecd27aa46fbbec93
+        .quad   0x130a155fc2e2a7f8
+        .quad   0x416b151ab706a1d5
+        .quad   0x56a8d7efe9c136b0
+        .quad   0xbd07e5cd58e44b20
+        .quad   0xafe62fda1b57e0ab
+        .quad   0x191a2af74277e8d2
+
+        // 2^44 * 1 * G
+
+        .quad   0xd550095bab6f4985
+        .quad   0x04f4cd5b4fbfaf1a
+        .quad   0x9d8e2ed12a0c7540
+        .quad   0x2bc24e04b2212286
+        .quad   0x09d4b60b2fe09a14
+        .quad   0xc384f0afdbb1747e
+        .quad   0x58e2ea8978b5fd6e
+        .quad   0x519ef577b5e09b0a
+        .quad   0x1863d7d91124cca9
+        .quad   0x7ac08145b88a708e
+        .quad   0x2bcd7309857031f5
+        .quad   0x62337a6e8ab8fae5
+
+        // 2^44 * 2 * G
+
+        .quad   0x4bcef17f06ffca16
+        .quad   0xde06e1db692ae16a
+        .quad   0x0753702d614f42b0
+        .quad   0x5f6041b45b9212d0
+        .quad   0xd1ab324e1b3a1273
+        .quad   0x18947cf181055340
+        .quad   0x3b5d9567a98c196e
+        .quad   0x7fa00425802e1e68
+        .quad   0x7d531574028c2705
+        .quad   0x80317d69db0d75fe
+        .quad   0x30fface8ef8c8ddd
+        .quad   0x7e9de97bb6c3e998
+
+        // 2^44 * 3 * G
+
+        .quad   0x1558967b9e6585a3
+        .quad   0x97c99ce098e98b92
+        .quad   0x10af149b6eb3adad
+        .quad   0x42181fe8f4d38cfa
+        .quad   0xf004be62a24d40dd
+        .quad   0xba0659910452d41f
+        .quad   0x81c45ee162a44234
+        .quad   0x4cb829d8a22266ef
+        .quad   0x1dbcaa8407b86681
+        .quad   0x081f001e8b26753b
+        .quad   0x3cd7ce6a84048e81
+        .quad   0x78af11633f25f22c
+
+        // 2^44 * 4 * G
+
+        .quad   0x8416ebd40b50babc
+        .quad   0x1508722628208bee
+        .quad   0xa3148fafb9c1c36d
+        .quad   0x0d07daacd32d7d5d
+        .quad   0x3241c00e7d65318c
+        .quad   0xe6bee5dcd0e86de7
+        .quad   0x118b2dc2fbc08c26
+        .quad   0x680d04a7fc603dc3
+        .quad   0xf9c2414a695aa3eb
+        .quad   0xdaa42c4c05a68f21
+        .quad   0x7c6c23987f93963e
+        .quad   0x210e8cd30c3954e3
+
+        // 2^44 * 5 * G
+
+        .quad   0xac4201f210a71c06
+        .quad   0x6a65e0aef3bfb021
+        .quad   0xbc42c35c393632f7
+        .quad   0x56ea8db1865f0742
+        .quad   0x2b50f16137fe6c26
+        .quad   0xe102bcd856e404d8
+        .quad   0x12b0f1414c561f6b
+        .quad   0x51b17bc8d028ec91
+        .quad   0xfff5fb4bcf535119
+        .quad   0xf4989d79df1108a0
+        .quad   0xbdfcea659a3ba325
+        .quad   0x18a11f1174d1a6f2
+
+        // 2^44 * 6 * G
+
+        .quad   0x407375ab3f6bba29
+        .quad   0x9ec3b6d8991e482e
+        .quad   0x99c80e82e55f92e9
+        .quad   0x307c13b6fb0c0ae1
+        .quad   0xfbd63cdad27a5f2c
+        .quad   0xf00fc4bc8aa106d7
+        .quad   0x53fb5c1a8e64a430
+        .quad   0x04eaabe50c1a2e85
+        .quad   0x24751021cb8ab5e7
+        .quad   0xfc2344495c5010eb
+        .quad   0x5f1e717b4e5610a1
+        .quad   0x44da5f18c2710cd5
+
+        // 2^44 * 7 * G
+
+        .quad   0x033cc55ff1b82eb5
+        .quad   0xb15ae36d411cae52
+        .quad   0xba40b6198ffbacd3
+        .quad   0x768edce1532e861f
+        .quad   0x9156fe6b89d8eacc
+        .quad   0xe6b79451e23126a1
+        .quad   0xbd7463d93944eb4e
+        .quad   0x726373f6767203ae
+        .quad   0xe305ca72eb7ef68a
+        .quad   0x662cf31f70eadb23
+        .quad   0x18f026fdb4c45b68
+        .quad   0x513b5384b5d2ecbd
+
+        // 2^44 * 8 * G
+
+        .quad   0x46d46280c729989e
+        .quad   0x4b93fbd05368a5dd
+        .quad   0x63df3f81d1765a89
+        .quad   0x34cebd64b9a0a223
+        .quad   0x5e2702878af34ceb
+        .quad   0x900b0409b946d6ae
+        .quad   0x6512ebf7dabd8512
+        .quad   0x61d9b76988258f81
+        .quad   0xa6c5a71349b7d94b
+        .quad   0xa3f3d15823eb9446
+        .quad   0x0416fbd277484834
+        .quad   0x69d45e6f2c70812f
+
+        // 2^48 * 1 * G
+
+        .quad   0xce16f74bc53c1431
+        .quad   0x2b9725ce2072edde
+        .quad   0xb8b9c36fb5b23ee7
+        .quad   0x7e2e0e450b5cc908
+        .quad   0x9fe62b434f460efb
+        .quad   0xded303d4a63607d6
+        .quad   0xf052210eb7a0da24
+        .quad   0x237e7dbe00545b93
+        .quad   0x013575ed6701b430
+        .quad   0x231094e69f0bfd10
+        .quad   0x75320f1583e47f22
+        .quad   0x71afa699b11155e3
+
+        // 2^48 * 2 * G
+
+        .quad   0x65ce6f9b3953b61d
+        .quad   0xc65839eaafa141e6
+        .quad   0x0f435ffda9f759fe
+        .quad   0x021142e9c2b1c28e
+        .quad   0xea423c1c473b50d6
+        .quad   0x51e87a1f3b38ef10
+        .quad   0x9b84bf5fb2c9be95
+        .quad   0x00731fbc78f89a1c
+        .quad   0xe430c71848f81880
+        .quad   0xbf960c225ecec119
+        .quad   0xb6dae0836bba15e3
+        .quad   0x4c4d6f3347e15808
+
+        // 2^48 * 3 * G
+
+        .quad   0x18f7eccfc17d1fc9
+        .quad   0x6c75f5a651403c14
+        .quad   0xdbde712bf7ee0cdf
+        .quad   0x193fddaaa7e47a22
+        .quad   0x2f0cddfc988f1970
+        .quad   0x6b916227b0b9f51b
+        .quad   0x6ec7b6c4779176be
+        .quad   0x38bf9500a88f9fa8
+        .quad   0x1fd2c93c37e8876f
+        .quad   0xa2f61e5a18d1462c
+        .quad   0x5080f58239241276
+        .quad   0x6a6fb99ebf0d4969
+
+        // 2^48 * 4 * G
+
+        .quad   0x6a46c1bb560855eb
+        .quad   0x2416bb38f893f09d
+        .quad   0xd71d11378f71acc1
+        .quad   0x75f76914a31896ea
+        .quad   0xeeb122b5b6e423c6
+        .quad   0x939d7010f286ff8e
+        .quad   0x90a92a831dcf5d8c
+        .quad   0x136fda9f42c5eb10
+        .quad   0xf94cdfb1a305bdd1
+        .quad   0x0f364b9d9ff82c08
+        .quad   0x2a87d8a5c3bb588a
+        .quad   0x022183510be8dcba
+
+        // 2^48 * 5 * G
+
+        .quad   0x4af766385ead2d14
+        .quad   0xa08ed880ca7c5830
+        .quad   0x0d13a6e610211e3d
+        .quad   0x6a071ce17b806c03
+        .quad   0x9d5a710143307a7f
+        .quad   0xb063de9ec47da45f
+        .quad   0x22bbfe52be927ad3
+        .quad   0x1387c441fd40426c
+        .quad   0xb5d3c3d187978af8
+        .quad   0x722b5a3d7f0e4413
+        .quad   0x0d7b4848bb477ca0
+        .quad   0x3171b26aaf1edc92
+
+        // 2^48 * 6 * G
+
+        .quad   0xa92f319097564ca8
+        .quad   0xff7bb84c2275e119
+        .quad   0x4f55fe37a4875150
+        .quad   0x221fd4873cf0835a
+        .quad   0xa60db7d8b28a47d1
+        .quad   0xa6bf14d61770a4f1
+        .quad   0xd4a1f89353ddbd58
+        .quad   0x6c514a63344243e9
+        .quad   0x2322204f3a156341
+        .quad   0xfb73e0e9ba0a032d
+        .quad   0xfce0dd4c410f030e
+        .quad   0x48daa596fb924aaa
+
+        // 2^48 * 7 * G
+
+        .quad   0x6eca8e665ca59cc7
+        .quad   0xa847254b2e38aca0
+        .quad   0x31afc708d21e17ce
+        .quad   0x676dd6fccad84af7
+        .quad   0x14f61d5dc84c9793
+        .quad   0x9941f9e3ef418206
+        .quad   0xcdf5b88f346277ac
+        .quad   0x58c837fa0e8a79a9
+        .quad   0x0cf9688596fc9058
+        .quad   0x1ddcbbf37b56a01b
+        .quad   0xdcc2e77d4935d66a
+        .quad   0x1c4f73f2c6a57f0a
+
+        // 2^48 * 8 * G
+
+        .quad   0x0e7a4fbd305fa0bb
+        .quad   0x829d4ce054c663ad
+        .quad   0xf421c3832fe33848
+        .quad   0x795ac80d1bf64c42
+        .quad   0xb36e706efc7c3484
+        .quad   0x73dfc9b4c3c1cf61
+        .quad   0xeb1d79c9781cc7e5
+        .quad   0x70459adb7daf675c
+        .quad   0x1b91db4991b42bb3
+        .quad   0x572696234b02dcca
+        .quad   0x9fdf9ee51f8c78dc
+        .quad   0x5fe162848ce21fd3
+
+        // 2^52 * 1 * G
+
+        .quad   0xe2790aae4d077c41
+        .quad   0x8b938270db7469a3
+        .quad   0x6eb632dc8abd16a2
+        .quad   0x720814ecaa064b72
+        .quad   0x315c29c795115389
+        .quad   0xd7e0e507862f74ce
+        .quad   0x0c4a762185927432
+        .quad   0x72de6c984a25a1e4
+        .quad   0xae9ab553bf6aa310
+        .quad   0x050a50a9806d6e1b
+        .quad   0x92bb7403adff5139
+        .quad   0x0394d27645be618b
+
+        // 2^52 * 2 * G
+
+        .quad   0x4d572251857eedf4
+        .quad   0xe3724edde19e93c5
+        .quad   0x8a71420e0b797035
+        .quad   0x3b3c833687abe743
+        .quad   0xf5396425b23545a4
+        .quad   0x15a7a27e98fbb296
+        .quad   0xab6c52bc636fdd86
+        .quad   0x79d995a8419334ee
+        .quad   0xcd8a8ea61195dd75
+        .quad   0xa504d8a81dd9a82f
+        .quad   0x540dca81a35879b6
+        .quad   0x60dd16a379c86a8a
+
+        // 2^52 * 3 * G
+
+        .quad   0x35a2c8487381e559
+        .quad   0x596ffea6d78082cb
+        .quad   0xcb9771ebdba7b653
+        .quad   0x5a08b5019b4da685
+        .quad   0x3501d6f8153e47b8
+        .quad   0xb7a9675414a2f60c
+        .quad   0x112ee8b6455d9523
+        .quad   0x4e62a3c18112ea8a
+        .quad   0xc8d4ac04516ab786
+        .quad   0x595af3215295b23d
+        .quad   0xd6edd234db0230c1
+        .quad   0x0929efe8825b41cc
+
+        // 2^52 * 4 * G
+
+        .quad   0x5f0601d1cbd0f2d3
+        .quad   0x736e412f6132bb7f
+        .quad   0x83604432238dde87
+        .quad   0x1e3a5272f5c0753c
+        .quad   0x8b3172b7ad56651d
+        .quad   0x01581b7a3fabd717
+        .quad   0x2dc94df6424df6e4
+        .quad   0x30376e5d2c29284f
+        .quad   0xd2918da78159a59c
+        .quad   0x6bdc1cd93f0713f3
+        .quad   0x565f7a934acd6590
+        .quad   0x53daacec4cb4c128
+
+        // 2^52 * 5 * G
+
+        .quad   0x4ca73bd79cc8a7d6
+        .quad   0x4d4a738f47e9a9b2
+        .quad   0xf4cbf12942f5fe00
+        .quad   0x01a13ff9bdbf0752
+        .quad   0x99852bc3852cfdb0
+        .quad   0x2cc12e9559d6ed0b
+        .quad   0x70f9e2bf9b5ac27b
+        .quad   0x4f3b8c117959ae99
+        .quad   0x55b6c9c82ff26412
+        .quad   0x1ac4a8c91fb667a8
+        .quad   0xd527bfcfeb778bf2
+        .quad   0x303337da7012a3be
+
+        // 2^52 * 6 * G
+
+        .quad   0x955422228c1c9d7c
+        .quad   0x01fac1371a9b340f
+        .quad   0x7e8d9177925b48d7
+        .quad   0x53f8ad5661b3e31b
+        .quad   0x976d3ccbfad2fdd1
+        .quad   0xcb88839737a640a8
+        .quad   0x2ff00c1d6734cb25
+        .quad   0x269ff4dc789c2d2b
+        .quad   0x0c003fbdc08d678d
+        .quad   0x4d982fa37ead2b17
+        .quad   0xc07e6bcdb2e582f1
+        .quad   0x296c7291df412a44
+
+        // 2^52 * 7 * G
+
+        .quad   0x7903de2b33daf397
+        .quad   0xd0ff0619c9a624b3
+        .quad   0x8a1d252b555b3e18
+        .quad   0x2b6d581c52e0b7c0
+        .quad   0xdfb23205dab8b59e
+        .quad   0x465aeaa0c8092250
+        .quad   0xd133c1189a725d18
+        .quad   0x2327370261f117d1
+        .quad   0x3d0543d3623e7986
+        .quad   0x679414c2c278a354
+        .quad   0xae43f0cc726196f6
+        .quad   0x7836c41f8245eaba
+
+        // 2^52 * 8 * G
+
+        .quad   0xe7a254db49e95a81
+        .quad   0x5192d5d008b0ad73
+        .quad   0x4d20e5b1d00afc07
+        .quad   0x5d55f8012cf25f38
+        .quad   0xca651e848011937c
+        .quad   0xc6b0c46e6ef41a28
+        .quad   0xb7021ba75f3f8d52
+        .quad   0x119dff99ead7b9fd
+        .quad   0x43eadfcbf4b31d4d
+        .quad   0xc6503f7411148892
+        .quad   0xfeee68c5060d3b17
+        .quad   0x329293b3dd4a0ac8
+
+        // 2^56 * 1 * G
+
+        .quad   0x4e59214fe194961a
+        .quad   0x49be7dc70d71cd4f
+        .quad   0x9300cfd23b50f22d
+        .quad   0x4789d446fc917232
+        .quad   0x2879852d5d7cb208
+        .quad   0xb8dedd70687df2e7
+        .quad   0xdc0bffab21687891
+        .quad   0x2b44c043677daa35
+        .quad   0x1a1c87ab074eb78e
+        .quad   0xfac6d18e99daf467
+        .quad   0x3eacbbcd484f9067
+        .quad   0x60c52eef2bb9a4e4
+
+        // 2^56 * 2 * G
+
+        .quad   0x0b5d89bc3bfd8bf1
+        .quad   0xb06b9237c9f3551a
+        .quad   0x0e4c16b0d53028f5
+        .quad   0x10bc9c312ccfcaab
+        .quad   0x702bc5c27cae6d11
+        .quad   0x44c7699b54a48cab
+        .quad   0xefbc4056ba492eb2
+        .quad   0x70d77248d9b6676d
+        .quad   0xaa8ae84b3ec2a05b
+        .quad   0x98699ef4ed1781e0
+        .quad   0x794513e4708e85d1
+        .quad   0x63755bd3a976f413
+
+        // 2^56 * 3 * G
+
+        .quad   0xb55fa03e2ad10853
+        .quad   0x356f75909ee63569
+        .quad   0x9ff9f1fdbe69b890
+        .quad   0x0d8cc1c48bc16f84
+        .quad   0x3dc7101897f1acb7
+        .quad   0x5dda7d5ec165bbd8
+        .quad   0x508e5b9c0fa1020f
+        .quad   0x2763751737c52a56
+        .quad   0x029402d36eb419a9
+        .quad   0xf0b44e7e77b460a5
+        .quad   0xcfa86230d43c4956
+        .quad   0x70c2dd8a7ad166e7
+
+        // 2^56 * 4 * G
+
+        .quad   0x656194509f6fec0e
+        .quad   0xee2e7ea946c6518d
+        .quad   0x9733c1f367e09b5c
+        .quad   0x2e0fac6363948495
+        .quad   0x91d4967db8ed7e13
+        .quad   0x74252f0ad776817a
+        .quad   0xe40982e00d852564
+        .quad   0x32b8613816a53ce5
+        .quad   0x79e7f7bee448cd64
+        .quad   0x6ac83a67087886d0
+        .quad   0xf89fd4d9a0e4db2e
+        .quad   0x4179215c735a4f41
+
+        // 2^56 * 5 * G
+
+        .quad   0x8c7094e7d7dced2a
+        .quad   0x97fb8ac347d39c70
+        .quad   0xe13be033a906d902
+        .quad   0x700344a30cd99d76
+        .quad   0xe4ae33b9286bcd34
+        .quad   0xb7ef7eb6559dd6dc
+        .quad   0x278b141fb3d38e1f
+        .quad   0x31fa85662241c286
+        .quad   0xaf826c422e3622f4
+        .quad   0xc12029879833502d
+        .quad   0x9bc1b7e12b389123
+        .quad   0x24bb2312a9952489
+
+        // 2^56 * 6 * G
+
+        .quad   0xb1a8ed1732de67c3
+        .quad   0x3cb49418461b4948
+        .quad   0x8ebd434376cfbcd2
+        .quad   0x0fee3e871e188008
+        .quad   0x41f80c2af5f85c6b
+        .quad   0x687284c304fa6794
+        .quad   0x8945df99a3ba1bad
+        .quad   0x0d1d2af9ffeb5d16
+        .quad   0xa9da8aa132621edf
+        .quad   0x30b822a159226579
+        .quad   0x4004197ba79ac193
+        .quad   0x16acd79718531d76
+
+        // 2^56 * 7 * G
+
+        .quad   0x72df72af2d9b1d3d
+        .quad   0x63462a36a432245a
+        .quad   0x3ecea07916b39637
+        .quad   0x123e0ef6b9302309
+        .quad   0xc959c6c57887b6ad
+        .quad   0x94e19ead5f90feba
+        .quad   0x16e24e62a342f504
+        .quad   0x164ed34b18161700
+        .quad   0x487ed94c192fe69a
+        .quad   0x61ae2cea3a911513
+        .quad   0x877bf6d3b9a4de27
+        .quad   0x78da0fc61073f3eb
+
+        // 2^56 * 8 * G
+
+        .quad   0x5bf15d28e52bc66a
+        .quad   0x2c47e31870f01a8e
+        .quad   0x2419afbc06c28bdd
+        .quad   0x2d25deeb256b173a
+        .quad   0xa29f80f1680c3a94
+        .quad   0x71f77e151ae9e7e6
+        .quad   0x1100f15848017973
+        .quad   0x054aa4b316b38ddd
+        .quad   0xdfc8468d19267cb8
+        .quad   0x0b28789c66e54daf
+        .quad   0x2aeb1d2a666eec17
+        .quad   0x134610a6ab7da760
+
+        // 2^60 * 1 * G
+
+        .quad   0xcaf55ec27c59b23f
+        .quad   0x99aeed3e154d04f2
+        .quad   0x68441d72e14141f4
+        .quad   0x140345133932a0a2
+        .quad   0xd91430e0dc028c3c
+        .quad   0x0eb955a85217c771
+        .quad   0x4b09e1ed2c99a1fa
+        .quad   0x42881af2bd6a743c
+        .quad   0x7bfec69aab5cad3d
+        .quad   0xc23e8cd34cb2cfad
+        .quad   0x685dd14bfb37d6a2
+        .quad   0x0ad6d64415677a18
+
+        // 2^60 * 2 * G
+
+        .quad   0x781a439e417becb5
+        .quad   0x4ac5938cd10e0266
+        .quad   0x5da385110692ac24
+        .quad   0x11b065a2ade31233
+        .quad   0x7914892847927e9f
+        .quad   0x33dad6ef370aa877
+        .quad   0x1f8f24fa11122703
+        .quad   0x5265ac2f2adf9592
+        .quad   0x405fdd309afcb346
+        .quad   0xd9723d4428e63f54
+        .quad   0x94c01df05f65aaae
+        .quad   0x43e4dc3ae14c0809
+
+        // 2^60 * 3 * G
+
+        .quad   0xbc12c7f1a938a517
+        .quad   0x473028ab3180b2e1
+        .quad   0x3f78571efbcd254a
+        .quad   0x74e534426ff6f90f
+        .quad   0xea6f7ac3adc2c6a3
+        .quad   0xd0e928f6e9717c94
+        .quad   0xe2d379ead645eaf5
+        .quad   0x46dd8785c51ffbbe
+        .quad   0x709801be375c8898
+        .quad   0x4b06dab5e3fd8348
+        .quad   0x75880ced27230714
+        .quad   0x2b09468fdd2f4c42
+
+        // 2^60 * 4 * G
+
+        .quad   0x97c749eeb701cb96
+        .quad   0x83f438d4b6a369c3
+        .quad   0x62962b8b9a402cd9
+        .quad   0x6976c7509888df7b
+        .quad   0x5b97946582ffa02a
+        .quad   0xda096a51fea8f549
+        .quad   0xa06351375f77af9b
+        .quad   0x1bcfde61201d1e76
+        .quad   0x4a4a5490246a59a2
+        .quad   0xd63ebddee87fdd90
+        .quad   0xd9437c670d2371fa
+        .quad   0x69e87308d30f8ed6
+
+        // 2^60 * 5 * G
+
+        .quad   0x435a8bb15656beb0
+        .quad   0xf8fac9ba4f4d5bca
+        .quad   0xb9b278c41548c075
+        .quad   0x3eb0ef76e892b622
+        .quad   0x0f80bf028bc80303
+        .quad   0x6aae16b37a18cefb
+        .quad   0xdd47ea47d72cd6a3
+        .quad   0x61943588f4ed39aa
+        .quad   0xd26e5c3e91039f85
+        .quad   0xc0e9e77df6f33aa9
+        .quad   0xe8968c5570066a93
+        .quad   0x3c34d1881faaaddd
+
+        // 2^60 * 6 * G
+
+        .quad   0x3f9d2b5ea09f9ec0
+        .quad   0x1dab3b6fb623a890
+        .quad   0xa09ba3ea72d926c4
+        .quad   0x374193513fd8b36d
+        .quad   0xbd5b0b8f2fffe0d9
+        .quad   0x6aa254103ed24fb9
+        .quad   0x2ac7d7bcb26821c4
+        .quad   0x605b394b60dca36a
+        .quad   0xb4e856e45a9d1ed2
+        .quad   0xefe848766c97a9a2
+        .quad   0xb104cf641e5eee7d
+        .quad   0x2f50b81c88a71c8f
+
+        // 2^60 * 7 * G
+
+        .quad   0x31723c61fc6811bb
+        .quad   0x9cb450486211800f
+        .quad   0x768933d347995753
+        .quad   0x3491a53502752fcd
+        .quad   0x2b552ca0a7da522a
+        .quad   0x3230b336449b0250
+        .quad   0xf2c4c5bca4b99fb9
+        .quad   0x7b2c674958074a22
+        .quad   0xd55165883ed28cdf
+        .quad   0x12d84fd2d362de39
+        .quad   0x0a874ad3e3378e4f
+        .quad   0x000d2b1f7c763e74
+
+        // 2^60 * 8 * G
+
+        .quad   0x3d420811d06d4a67
+        .quad   0xbefc048590e0ffe3
+        .quad   0xf870c6b7bd487bde
+        .quad   0x6e2a7316319afa28
+        .quad   0x9624778c3e94a8ab
+        .quad   0x0ad6f3cee9a78bec
+        .quad   0x948ac7810d743c4f
+        .quad   0x76627935aaecfccc
+        .quad   0x56a8ac24d6d59a9f
+        .quad   0xc8db753e3096f006
+        .quad   0x477f41e68f4c5299
+        .quad   0x588d851cf6c86114
+
+        // 2^64 * 1 * G
+
+        .quad   0x51138ec78df6b0fe
+        .quad   0x5397da89e575f51b
+        .quad   0x09207a1d717af1b9
+        .quad   0x2102fdba2b20d650
+        .quad   0xcd2a65e777d1f515
+        .quad   0x548991878faa60f1
+        .quad   0xb1b73bbcdabc06e5
+        .quad   0x654878cba97cc9fb
+        .quad   0x969ee405055ce6a1
+        .quad   0x36bca7681251ad29
+        .quad   0x3a1af517aa7da415
+        .quad   0x0ad725db29ecb2ba
+
+        // 2^64 * 2 * G
+
+        .quad   0xdc4267b1834e2457
+        .quad   0xb67544b570ce1bc5
+        .quad   0x1af07a0bf7d15ed7
+        .quad   0x4aefcffb71a03650
+        .quad   0xfec7bc0c9b056f85
+        .quad   0x537d5268e7f5ffd7
+        .quad   0x77afc6624312aefa
+        .quad   0x4f675f5302399fd9
+        .quad   0xc32d36360415171e
+        .quad   0xcd2bef118998483b
+        .quad   0x870a6eadd0945110
+        .quad   0x0bccbb72a2a86561
+
+        // 2^64 * 3 * G
+
+        .quad   0x185e962feab1a9c8
+        .quad   0x86e7e63565147dcd
+        .quad   0xb092e031bb5b6df2
+        .quad   0x4024f0ab59d6b73e
+        .quad   0x186d5e4c50fe1296
+        .quad   0xe0397b82fee89f7e
+        .quad   0x3bc7f6c5507031b0
+        .quad   0x6678fd69108f37c2
+        .quad   0x1586fa31636863c2
+        .quad   0x07f68c48572d33f2
+        .quad   0x4f73cc9f789eaefc
+        .quad   0x2d42e2108ead4701
+
+        // 2^64 * 4 * G
+
+        .quad   0x97f5131594dfd29b
+        .quad   0x6155985d313f4c6a
+        .quad   0xeba13f0708455010
+        .quad   0x676b2608b8d2d322
+        .quad   0x21717b0d0f537593
+        .quad   0x914e690b131e064c
+        .quad   0x1bb687ae752ae09f
+        .quad   0x420bf3a79b423c6e
+        .quad   0x8138ba651c5b2b47
+        .quad   0x8671b6ec311b1b80
+        .quad   0x7bff0cb1bc3135b0
+        .quad   0x745d2ffa9c0cf1e0
+
+        // 2^64 * 5 * G
+
+        .quad   0xbf525a1e2bc9c8bd
+        .quad   0xea5b260826479d81
+        .quad   0xd511c70edf0155db
+        .quad   0x1ae23ceb960cf5d0
+        .quad   0x6036df5721d34e6a
+        .quad   0xb1db8827997bb3d0
+        .quad   0xd3c209c3c8756afa
+        .quad   0x06e15be54c1dc839
+        .quad   0x5b725d871932994a
+        .quad   0x32351cb5ceb1dab0
+        .quad   0x7dc41549dab7ca05
+        .quad   0x58ded861278ec1f7
+
+        // 2^64 * 6 * G
+
+        .quad   0xd8173793f266c55c
+        .quad   0xc8c976c5cc454e49
+        .quad   0x5ce382f8bc26c3a8
+        .quad   0x2ff39de85485f6f9
+        .quad   0x2dfb5ba8b6c2c9a8
+        .quad   0x48eeef8ef52c598c
+        .quad   0x33809107f12d1573
+        .quad   0x08ba696b531d5bd8
+        .quad   0x77ed3eeec3efc57a
+        .quad   0x04e05517d4ff4811
+        .quad   0xea3d7a3ff1a671cb
+        .quad   0x120633b4947cfe54
+
+        // 2^64 * 7 * G
+
+        .quad   0x0b94987891610042
+        .quad   0x4ee7b13cecebfae8
+        .quad   0x70be739594f0a4c0
+        .quad   0x35d30a99b4d59185
+        .quad   0x82bd31474912100a
+        .quad   0xde237b6d7e6fbe06
+        .quad   0xe11e761911ea79c6
+        .quad   0x07433be3cb393bde
+        .quad   0xff7944c05ce997f4
+        .quad   0x575d3de4b05c51a3
+        .quad   0x583381fd5a76847c
+        .quad   0x2d873ede7af6da9f
+
+        // 2^64 * 8 * G
+
+        .quad   0x157a316443373409
+        .quad   0xfab8b7eef4aa81d9
+        .quad   0xb093fee6f5a64806
+        .quad   0x2e773654707fa7b6
+        .quad   0xaa6202e14e5df981
+        .quad   0xa20d59175015e1f5
+        .quad   0x18a275d3bae21d6c
+        .quad   0x0543618a01600253
+        .quad   0x0deabdf4974c23c1
+        .quad   0xaa6f0a259dce4693
+        .quad   0x04202cb8a29aba2c
+        .quad   0x4b1443362d07960d
+
+        // 2^68 * 1 * G
+
+        .quad   0x47b837f753242cec
+        .quad   0x256dc48cc04212f2
+        .quad   0xe222fbfbe1d928c5
+        .quad   0x48ea295bad8a2c07
+        .quad   0x299b1c3f57c5715e
+        .quad   0x96cb929e6b686d90
+        .quad   0x3004806447235ab3
+        .quad   0x2c435c24a44d9fe1
+        .quad   0x0607c97c80f8833f
+        .quad   0x0e851578ca25ec5b
+        .quad   0x54f7450b161ebb6f
+        .quad   0x7bcb4792a0def80e
+
+        // 2^68 * 2 * G
+
+        .quad   0x8487e3d02bc73659
+        .quad   0x4baf8445059979df
+        .quad   0xd17c975adcad6fbf
+        .quad   0x57369f0bdefc96b6
+        .quad   0x1cecd0a0045224c2
+        .quad   0x757f1b1b69e53952
+        .quad   0x775b7a925289f681
+        .quad   0x1b6cc62016736148
+        .quad   0xf1a9990175638698
+        .quad   0x353dd1beeeaa60d3
+        .quad   0x849471334c9ba488
+        .quad   0x63fa6e6843ade311
+
+        // 2^68 * 3 * G
+
+        .quad   0xd15c20536597c168
+        .quad   0x9f73740098d28789
+        .quad   0x18aee7f13257ba1f
+        .quad   0x3418bfda07346f14
+        .quad   0x2195becdd24b5eb7
+        .quad   0x5e41f18cc0cd44f9
+        .quad   0xdf28074441ca9ede
+        .quad   0x07073b98f35b7d67
+        .quad   0xd03c676c4ce530d4
+        .quad   0x0b64c0473b5df9f4
+        .quad   0x065cef8b19b3a31e
+        .quad   0x3084d661533102c9
+
+        // 2^68 * 4 * G
+
+        .quad   0xe1f6b79ebf8469ad
+        .quad   0x15801004e2663135
+        .quad   0x9a498330af74181b
+        .quad   0x3ba2504f049b673c
+        .quad   0x9a6ce876760321fd
+        .quad   0x7fe2b5109eb63ad8
+        .quad   0x00e7d4ae8ac80592
+        .quad   0x73d86b7abb6f723a
+        .quad   0x0b52b5606dba5ab6
+        .quad   0xa9134f0fbbb1edab
+        .quad   0x30a9520d9b04a635
+        .quad   0x6813b8f37973e5db
+
+        // 2^68 * 5 * G
+
+        .quad   0x9854b054334127c1
+        .quad   0x105d047882fbff25
+        .quad   0xdb49f7f944186f4f
+        .quad   0x1768e838bed0b900
+        .quad   0xf194ca56f3157e29
+        .quad   0x136d35705ef528a5
+        .quad   0xdd4cef778b0599bc
+        .quad   0x7d5472af24f833ed
+        .quad   0xd0ef874daf33da47
+        .quad   0x00d3be5db6e339f9
+        .quad   0x3f2a8a2f9c9ceece
+        .quad   0x5d1aeb792352435a
+
+        // 2^68 * 6 * G
+
+        .quad   0xf59e6bb319cd63ca
+        .quad   0x670c159221d06839
+        .quad   0xb06d565b2150cab6
+        .quad   0x20fb199d104f12a3
+        .quad   0x12c7bfaeb61ba775
+        .quad   0xb84e621fe263bffd
+        .quad   0x0b47a5c35c840dcf
+        .quad   0x7e83be0bccaf8634
+        .quad   0x61943dee6d99c120
+        .quad   0x86101f2e460b9fe0
+        .quad   0x6bb2f1518ee8598d
+        .quad   0x76b76289fcc475cc
+
+        // 2^68 * 7 * G
+
+        .quad   0x791b4cc1756286fa
+        .quad   0xdbced317d74a157c
+        .quad   0x7e732421ea72bde6
+        .quad   0x01fe18491131c8e9
+        .quad   0x4245f1a1522ec0b3
+        .quad   0x558785b22a75656d
+        .quad   0x1d485a2548a1b3c0
+        .quad   0x60959eccd58fe09f
+        .quad   0x3ebfeb7ba8ed7a09
+        .quad   0x49fdc2bbe502789c
+        .quad   0x44ebce5d3c119428
+        .quad   0x35e1eb55be947f4a
+
+        // 2^68 * 8 * G
+
+        .quad   0xdbdae701c5738dd3
+        .quad   0xf9c6f635b26f1bee
+        .quad   0x61e96a8042f15ef4
+        .quad   0x3aa1d11faf60a4d8
+        .quad   0x14fd6dfa726ccc74
+        .quad   0x3b084cfe2f53b965
+        .quad   0xf33ae4f552a2c8b4
+        .quad   0x59aab07a0d40166a
+        .quad   0x77bcec4c925eac25
+        .quad   0x1848718460137738
+        .quad   0x5b374337fea9f451
+        .quad   0x1865e78ec8e6aa46
+
+        // 2^72 * 1 * G
+
+        .quad   0xccc4b7c7b66e1f7a
+        .quad   0x44157e25f50c2f7e
+        .quad   0x3ef06dfc713eaf1c
+        .quad   0x582f446752da63f7
+        .quad   0x967c54e91c529ccb
+        .quad   0x30f6269264c635fb
+        .quad   0x2747aff478121965
+        .quad   0x17038418eaf66f5c
+        .quad   0xc6317bd320324ce4
+        .quad   0xa81042e8a4488bc4
+        .quad   0xb21ef18b4e5a1364
+        .quad   0x0c2a1c4bcda28dc9
+
+        // 2^72 * 2 * G
+
+        .quad   0xd24dc7d06f1f0447
+        .quad   0xb2269e3edb87c059
+        .quad   0xd15b0272fbb2d28f
+        .quad   0x7c558bd1c6f64877
+        .quad   0xedc4814869bd6945
+        .quad   0x0d6d907dbe1c8d22
+        .quad   0xc63bd212d55cc5ab
+        .quad   0x5a6a9b30a314dc83
+        .quad   0xd0ec1524d396463d
+        .quad   0x12bb628ac35a24f0
+        .quad   0xa50c3a791cbc5fa4
+        .quad   0x0404a5ca0afbafc3
+
+        // 2^72 * 3 * G
+
+        .quad   0x8c1f40070aa743d6
+        .quad   0xccbad0cb5b265ee8
+        .quad   0x574b046b668fd2de
+        .quad   0x46395bfdcadd9633
+        .quad   0x62bc9e1b2a416fd1
+        .quad   0xb5c6f728e350598b
+        .quad   0x04343fd83d5d6967
+        .quad   0x39527516e7f8ee98
+        .quad   0x117fdb2d1a5d9a9c
+        .quad   0x9c7745bcd1005c2a
+        .quad   0xefd4bef154d56fea
+        .quad   0x76579a29e822d016
+
+        // 2^72 * 4 * G
+
+        .quad   0x45b68e7e49c02a17
+        .quad   0x23cd51a2bca9a37f
+        .quad   0x3ed65f11ec224c1b
+        .quad   0x43a384dc9e05bdb1
+        .quad   0x333cb51352b434f2
+        .quad   0xd832284993de80e1
+        .quad   0xb5512887750d35ce
+        .quad   0x02c514bb2a2777c1
+        .quad   0x684bd5da8bf1b645
+        .quad   0xfb8bd37ef6b54b53
+        .quad   0x313916d7a9b0d253
+        .quad   0x1160920961548059
+
+        // 2^72 * 5 * G
+
+        .quad   0xb44d166929dacfaa
+        .quad   0xda529f4c8413598f
+        .quad   0xe9ef63ca453d5559
+        .quad   0x351e125bc5698e0b
+        .quad   0x7a385616369b4dcd
+        .quad   0x75c02ca7655c3563
+        .quad   0x7dc21bf9d4f18021
+        .quad   0x2f637d7491e6e042
+        .quad   0xd4b49b461af67bbe
+        .quad   0xd603037ac8ab8961
+        .quad   0x71dee19ff9a699fb
+        .quad   0x7f182d06e7ce2a9a
+
+        // 2^72 * 6 * G
+
+        .quad   0x7a7c8e64ab0168ec
+        .quad   0xcb5a4a5515edc543
+        .quad   0x095519d347cd0eda
+        .quad   0x67d4ac8c343e93b0
+        .quad   0x09454b728e217522
+        .quad   0xaa58e8f4d484b8d8
+        .quad   0xd358254d7f46903c
+        .quad   0x44acc043241c5217
+        .quad   0x1c7d6bbb4f7a5777
+        .quad   0x8b35fed4918313e1
+        .quad   0x4adca1c6c96b4684
+        .quad   0x556d1c8312ad71bd
+
+        // 2^72 * 7 * G
+
+        .quad   0x17ef40e30c8d3982
+        .quad   0x31f7073e15a3fa34
+        .quad   0x4f21f3cb0773646e
+        .quad   0x746c6c6d1d824eff
+        .quad   0x81f06756b11be821
+        .quad   0x0faff82310a3f3dd
+        .quad   0xf8b2d0556a99465d
+        .quad   0x097abe38cc8c7f05
+        .quad   0x0c49c9877ea52da4
+        .quad   0x4c4369559bdc1d43
+        .quad   0x022c3809f7ccebd2
+        .quad   0x577e14a34bee84bd
+
+        // 2^72 * 8 * G
+
+        .quad   0xf0e268ac61a73b0a
+        .quad   0xf2fafa103791a5f5
+        .quad   0xc1e13e826b6d00e9
+        .quad   0x60fa7ee96fd78f42
+        .quad   0x94fecebebd4dd72b
+        .quad   0xf46a4fda060f2211
+        .quad   0x124a5977c0c8d1ff
+        .quad   0x705304b8fb009295
+        .quad   0xb63d1d354d296ec6
+        .quad   0xf3c3053e5fad31d8
+        .quad   0x670b958cb4bd42ec
+        .quad   0x21398e0ca16353fd
+
+        // 2^76 * 1 * G
+
+        .quad   0x216ab2ca8da7d2ef
+        .quad   0x366ad9dd99f42827
+        .quad   0xae64b9004fdd3c75
+        .quad   0x403a395b53909e62
+        .quad   0x86c5fc16861b7e9a
+        .quad   0xf6a330476a27c451
+        .quad   0x01667267a1e93597
+        .quad   0x05ffb9cd6082dfeb
+        .quad   0xa617fa9ff53f6139
+        .quad   0x60f2b5e513e66cb6
+        .quad   0xd7a8beefb3448aa4
+        .quad   0x7a2932856f5ea192
+
+        // 2^76 * 2 * G
+
+        .quad   0x0b39d761b02de888
+        .quad   0x5f550e7ed2414e1f
+        .quad   0xa6bfa45822e1a940
+        .quad   0x050a2f7dfd447b99
+        .quad   0xb89c444879639302
+        .quad   0x4ae4f19350c67f2c
+        .quad   0xf0b35da8c81af9c6
+        .quad   0x39d0003546871017
+        .quad   0x437c3b33a650db77
+        .quad   0x6bafe81dbac52bb2
+        .quad   0xfe99402d2db7d318
+        .quad   0x2b5b7eec372ba6ce
+
+        // 2^76 * 3 * G
+
+        .quad   0xb3bc4bbd83f50eef
+        .quad   0x508f0c998c927866
+        .quad   0x43e76587c8b7e66e
+        .quad   0x0f7655a3a47f98d9
+        .quad   0xa694404d613ac8f4
+        .quad   0x500c3c2bfa97e72c
+        .quad   0x874104d21fcec210
+        .quad   0x1b205fb38604a8ee
+        .quad   0x55ecad37d24b133c
+        .quad   0x441e147d6038c90b
+        .quad   0x656683a1d62c6fee
+        .quad   0x0157d5dc87e0ecae
+
+        // 2^76 * 4 * G
+
+        .quad   0xf2a7af510354c13d
+        .quad   0xd7a0b145aa372b60
+        .quad   0x2869b96a05a3d470
+        .quad   0x6528e42d82460173
+        .quad   0x95265514d71eb524
+        .quad   0xe603d8815df14593
+        .quad   0x147cdf410d4de6b7
+        .quad   0x5293b1730437c850
+        .quad   0x23d0e0814bccf226
+        .quad   0x92c745cd8196fb93
+        .quad   0x8b61796c59541e5b
+        .quad   0x40a44df0c021f978
+
+        // 2^76 * 5 * G
+
+        .quad   0xdaa869894f20ea6a
+        .quad   0xea14a3d14c620618
+        .quad   0x6001fccb090bf8be
+        .quad   0x35f4e822947e9cf0
+        .quad   0x86c96e514bc5d095
+        .quad   0xf20d4098fca6804a
+        .quad   0x27363d89c826ea5d
+        .quad   0x39ca36565719cacf
+        .quad   0x97506f2f6f87b75c
+        .quad   0xc624aea0034ae070
+        .quad   0x1ec856e3aad34dd6
+        .quad   0x055b0be0e440e58f
+
+        // 2^76 * 6 * G
+
+        .quad   0x6469a17d89735d12
+        .quad   0xdb6f27d5e662b9f1
+        .quad   0x9fcba3286a395681
+        .quad   0x363b8004d269af25
+        .quad   0x4d12a04b6ea33da2
+        .quad   0x57cf4c15e36126dd
+        .quad   0x90ec9675ee44d967
+        .quad   0x64ca348d2a985aac
+        .quad   0x99588e19e4c4912d
+        .quad   0xefcc3b4e1ca5ce6b
+        .quad   0x4522ea60fa5b98d5
+        .quad   0x7064bbab1de4a819
+
+        // 2^76 * 7 * G
+
+        .quad   0xb919e1515a770641
+        .quad   0xa9a2e2c74e7f8039
+        .quad   0x7527250b3df23109
+        .quad   0x756a7330ac27b78b
+        .quad   0xa290c06142542129
+        .quad   0xf2e2c2aebe8d5b90
+        .quad   0xcf2458db76abfe1b
+        .quad   0x02157ade83d626bf
+        .quad   0x3e46972a1b9a038b
+        .quad   0x2e4ee66a7ee03fb4
+        .quad   0x81a248776edbb4ca
+        .quad   0x1a944ee88ecd0563
+
+        // 2^76 * 8 * G
+
+        .quad   0xd5a91d1151039372
+        .quad   0x2ed377b799ca26de
+        .quad   0xa17202acfd366b6b
+        .quad   0x0730291bd6901995
+        .quad   0xbb40a859182362d6
+        .quad   0xb99f55778a4d1abb
+        .quad   0x8d18b427758559f6
+        .quad   0x26c20fe74d26235a
+        .quad   0x648d1d9fe9cc22f5
+        .quad   0x66bc561928dd577c
+        .quad   0x47d3ed21652439d1
+        .quad   0x49d271acedaf8b49
+
+        // 2^80 * 1 * G
+
+        .quad   0x89f5058a382b33f3
+        .quad   0x5ae2ba0bad48c0b4
+        .quad   0x8f93b503a53db36e
+        .quad   0x5aa3ed9d95a232e6
+        .quad   0x2798aaf9b4b75601
+        .quad   0x5eac72135c8dad72
+        .quad   0xd2ceaa6161b7a023
+        .quad   0x1bbfb284e98f7d4e
+        .quad   0x656777e9c7d96561
+        .quad   0xcb2b125472c78036
+        .quad   0x65053299d9506eee
+        .quad   0x4a07e14e5e8957cc
+
+        // 2^80 * 2 * G
+
+        .quad   0x4ee412cb980df999
+        .quad   0xa315d76f3c6ec771
+        .quad   0xbba5edde925c77fd
+        .quad   0x3f0bac391d313402
+        .quad   0x240b58cdc477a49b
+        .quad   0xfd38dade6447f017
+        .quad   0x19928d32a7c86aad
+        .quad   0x50af7aed84afa081
+        .quad   0x6e4fde0115f65be5
+        .quad   0x29982621216109b2
+        .quad   0x780205810badd6d9
+        .quad   0x1921a316baebd006
+
+        // 2^80 * 3 * G
+
+        .quad   0x89422f7edfb870fc
+        .quad   0x2c296beb4f76b3bd
+        .quad   0x0738f1d436c24df7
+        .quad   0x6458df41e273aeb0
+        .quad   0xd75aad9ad9f3c18b
+        .quad   0x566a0eef60b1c19c
+        .quad   0x3e9a0bac255c0ed9
+        .quad   0x7b049deca062c7f5
+        .quad   0xdccbe37a35444483
+        .quad   0x758879330fedbe93
+        .quad   0x786004c312c5dd87
+        .quad   0x6093dccbc2950e64
+
+        // 2^80 * 4 * G
+
+        .quad   0x1ff39a8585e0706d
+        .quad   0x36d0a5d8b3e73933
+        .quad   0x43b9f2e1718f453b
+        .quad   0x57d1ea084827a97c
+        .quad   0x6bdeeebe6084034b
+        .quad   0x3199c2b6780fb854
+        .quad   0x973376abb62d0695
+        .quad   0x6e3180c98b647d90
+        .quad   0xee7ab6e7a128b071
+        .quad   0xa4c1596d93a88baa
+        .quad   0xf7b4de82b2216130
+        .quad   0x363e999ddd97bd18
+
+        // 2^80 * 5 * G
+
+        .quad   0x96a843c135ee1fc4
+        .quad   0x976eb35508e4c8cf
+        .quad   0xb42f6801b58cd330
+        .quad   0x48ee9b78693a052b
+        .quad   0x2f1848dce24baec6
+        .quad   0x769b7255babcaf60
+        .quad   0x90cb3c6e3cefe931
+        .quad   0x231f979bc6f9b355
+        .quad   0x5c31de4bcc2af3c6
+        .quad   0xb04bb030fe208d1f
+        .quad   0xb78d7009c14fb466
+        .quad   0x079bfa9b08792413
+
+        // 2^80 * 6 * G
+
+        .quad   0xe3903a51da300df4
+        .quad   0x843964233da95ab0
+        .quad   0xed3cf12d0b356480
+        .quad   0x038c77f684817194
+        .quad   0xf3c9ed80a2d54245
+        .quad   0x0aa08b7877f63952
+        .quad   0xd76dac63d1085475
+        .quad   0x1ef4fb159470636b
+        .quad   0x854e5ee65b167bec
+        .quad   0x59590a4296d0cdc2
+        .quad   0x72b2df3498102199
+        .quad   0x575ee92a4a0bff56
+
+        // 2^80 * 7 * G
+
+        .quad   0xd4c080908a182fcf
+        .quad   0x30e170c299489dbd
+        .quad   0x05babd5752f733de
+        .quad   0x43d4e7112cd3fd00
+        .quad   0x5d46bc450aa4d801
+        .quad   0xc3af1227a533b9d8
+        .quad   0x389e3b262b8906c2
+        .quad   0x200a1e7e382f581b
+        .quad   0x518db967eaf93ac5
+        .quad   0x71bc989b056652c0
+        .quad   0xfe2b85d9567197f5
+        .quad   0x050eca52651e4e38
+
+        // 2^80 * 8 * G
+
+        .quad   0xc3431ade453f0c9c
+        .quad   0xe9f5045eff703b9b
+        .quad   0xfcd97ac9ed847b3d
+        .quad   0x4b0ee6c21c58f4c6
+        .quad   0x97ac397660e668ea
+        .quad   0x9b19bbfe153ab497
+        .quad   0x4cb179b534eca79f
+        .quad   0x6151c09fa131ae57
+        .quad   0x3af55c0dfdf05d96
+        .quad   0xdd262ee02ab4ee7a
+        .quad   0x11b2bb8712171709
+        .quad   0x1fef24fa800f030b
+
+        // 2^84 * 1 * G
+
+        .quad   0xb496123a6b6c6609
+        .quad   0xa750fe8580ab5938
+        .quad   0xf471bf39b7c27a5f
+        .quad   0x507903ce77ac193c
+        .quad   0xff91a66a90166220
+        .quad   0xf22552ae5bf1e009
+        .quad   0x7dff85d87f90df7c
+        .quad   0x4f620ffe0c736fb9
+        .quad   0x62f90d65dfde3e34
+        .quad   0xcf28c592b9fa5fad
+        .quad   0x99c86ef9c6164510
+        .quad   0x25d448044a256c84
+
+        // 2^84 * 2 * G
+
+        .quad   0xbd68230ec7e9b16f
+        .quad   0x0eb1b9c1c1c5795d
+        .quad   0x7943c8c495b6b1ff
+        .quad   0x2f9faf620bbacf5e
+        .quad   0x2c7c4415c9022b55
+        .quad   0x56a0d241812eb1fe
+        .quad   0xf02ea1c9d7b65e0d
+        .quad   0x4180512fd5323b26
+        .quad   0xa4ff3e698a48a5db
+        .quad   0xba6a3806bd95403b
+        .quad   0x9f7ce1af47d5b65d
+        .quad   0x15e087e55939d2fb
+
+        // 2^84 * 3 * G
+
+        .quad   0x12207543745c1496
+        .quad   0xdaff3cfdda38610c
+        .quad   0xe4e797272c71c34f
+        .quad   0x39c07b1934bdede9
+        .quad   0x8894186efb963f38
+        .quad   0x48a00e80dc639bd5
+        .quad   0xa4e8092be96c1c99
+        .quad   0x5a097d54ca573661
+        .quad   0x2d45892b17c9e755
+        .quad   0xd033fd7289308df8
+        .quad   0x6c2fe9d9525b8bd9
+        .quad   0x2edbecf1c11cc079
+
+        // 2^84 * 4 * G
+
+        .quad   0x1616a4e3c715a0d2
+        .quad   0x53623cb0f8341d4d
+        .quad   0x96ef5329c7e899cb
+        .quad   0x3d4e8dbba668baa6
+        .quad   0xee0f0fddd087a25f
+        .quad   0x9c7531555c3e34ee
+        .quad   0x660c572e8fab3ab5
+        .quad   0x0854fc44544cd3b2
+        .quad   0x61eba0c555edad19
+        .quad   0x24b533fef0a83de6
+        .quad   0x3b77042883baa5f8
+        .quad   0x678f82b898a47e8d
+
+        // 2^84 * 5 * G
+
+        .quad   0xb1491d0bd6900c54
+        .quad   0x3539722c9d132636
+        .quad   0x4db928920b362bc9
+        .quad   0x4d7cd1fea68b69df
+        .quad   0x1e09d94057775696
+        .quad   0xeed1265c3cd951db
+        .quad   0xfa9dac2b20bce16f
+        .quad   0x0f7f76e0e8d089f4
+        .quad   0x36d9ebc5d485b00c
+        .quad   0xa2596492e4adb365
+        .quad   0xc1659480c2119ccd
+        .quad   0x45306349186e0d5f
+
+        // 2^84 * 6 * G
+
+        .quad   0x94ddd0c1a6cdff1d
+        .quad   0x55f6f115e84213ae
+        .quad   0x6c935f85992fcf6a
+        .quad   0x067ee0f54a37f16f
+        .quad   0x96a414ec2b072491
+        .quad   0x1bb2218127a7b65b
+        .quad   0x6d2849596e8a4af0
+        .quad   0x65f3b08ccd27765f
+        .quad   0xecb29fff199801f7
+        .quad   0x9d361d1fa2a0f72f
+        .quad   0x25f11d2375fd2f49
+        .quad   0x124cefe80fe10fe2
+
+        // 2^84 * 7 * G
+
+        .quad   0x4c126cf9d18df255
+        .quad   0xc1d471e9147a63b6
+        .quad   0x2c6d3c73f3c93b5f
+        .quad   0x6be3a6a2e3ff86a2
+        .quad   0x1518e85b31b16489
+        .quad   0x8faadcb7db710bfb
+        .quad   0x39b0bdf4a14ae239
+        .quad   0x05f4cbea503d20c1
+        .quad   0xce040e9ec04145bc
+        .quad   0xc71ff4e208f6834c
+        .quad   0xbd546e8dab8847a3
+        .quad   0x64666aa0a4d2aba5
+
+        // 2^84 * 8 * G
+
+        .quad   0x6841435a7c06d912
+        .quad   0xca123c21bb3f830b
+        .quad   0xd4b37b27b1cbe278
+        .quad   0x1d753b84c76f5046
+        .quad   0xb0c53bf73337e94c
+        .quad   0x7cb5697e11e14f15
+        .quad   0x4b84abac1930c750
+        .quad   0x28dd4abfe0640468
+        .quad   0x7dc0b64c44cb9f44
+        .quad   0x18a3e1ace3925dbf
+        .quad   0x7a3034862d0457c4
+        .quad   0x4c498bf78a0c892e
+
+        // 2^88 * 1 * G
+
+        .quad   0x37d653fb1aa73196
+        .quad   0x0f9495303fd76418
+        .quad   0xad200b09fb3a17b2
+        .quad   0x544d49292fc8613e
+        .quad   0x22d2aff530976b86
+        .quad   0x8d90b806c2d24604
+        .quad   0xdca1896c4de5bae5
+        .quad   0x28005fe6c8340c17
+        .quad   0x6aefba9f34528688
+        .quad   0x5c1bff9425107da1
+        .quad   0xf75bbbcd66d94b36
+        .quad   0x72e472930f316dfa
+
+        // 2^88 * 2 * G
+
+        .quad   0x2695208c9781084f
+        .quad   0xb1502a0b23450ee1
+        .quad   0xfd9daea603efde02
+        .quad   0x5a9d2e8c2733a34c
+        .quad   0x07f3f635d32a7627
+        .quad   0x7aaa4d865f6566f0
+        .quad   0x3c85e79728d04450
+        .quad   0x1fee7f000fe06438
+        .quad   0x765305da03dbf7e5
+        .quad   0xa4daf2491434cdbd
+        .quad   0x7b4ad5cdd24a88ec
+        .quad   0x00f94051ee040543
+
+        // 2^88 * 3 * G
+
+        .quad   0x8d356b23c3d330b2
+        .quad   0xf21c8b9bb0471b06
+        .quad   0xb36c316c6e42b83c
+        .quad   0x07d79c7e8beab10d
+        .quad   0xd7ef93bb07af9753
+        .quad   0x583ed0cf3db766a7
+        .quad   0xce6998bf6e0b1ec5
+        .quad   0x47b7ffd25dd40452
+        .quad   0x87fbfb9cbc08dd12
+        .quad   0x8a066b3ae1eec29b
+        .quad   0x0d57242bdb1fc1bf
+        .quad   0x1c3520a35ea64bb6
+
+        // 2^88 * 4 * G
+
+        .quad   0x80d253a6bccba34a
+        .quad   0x3e61c3a13838219b
+        .quad   0x90c3b6019882e396
+        .quad   0x1c3d05775d0ee66f
+        .quad   0xcda86f40216bc059
+        .quad   0x1fbb231d12bcd87e
+        .quad   0xb4956a9e17c70990
+        .quad   0x38750c3b66d12e55
+        .quad   0x692ef1409422e51a
+        .quad   0xcbc0c73c2b5df671
+        .quad   0x21014fe7744ce029
+        .quad   0x0621e2c7d330487c
+
+        // 2^88 * 5 * G
+
+        .quad   0xaf9860cc8259838d
+        .quad   0x90ea48c1c69f9adc
+        .quad   0x6526483765581e30
+        .quad   0x0007d6097bd3a5bc
+        .quad   0xb7ae1796b0dbf0f3
+        .quad   0x54dfafb9e17ce196
+        .quad   0x25923071e9aaa3b4
+        .quad   0x5d8e589ca1002e9d
+        .quad   0xc0bf1d950842a94b
+        .quad   0xb2d3c363588f2e3e
+        .quad   0x0a961438bb51e2ef
+        .quad   0x1583d7783c1cbf86
+
+        // 2^88 * 6 * G
+
+        .quad   0xeceea2ef5da27ae1
+        .quad   0x597c3a1455670174
+        .quad   0xc9a62a126609167a
+        .quad   0x252a5f2e81ed8f70
+        .quad   0x90034704cc9d28c7
+        .quad   0x1d1b679ef72cc58f
+        .quad   0x16e12b5fbe5b8726
+        .quad   0x4958064e83c5580a
+        .quad   0x0d2894265066e80d
+        .quad   0xfcc3f785307c8c6b
+        .quad   0x1b53da780c1112fd
+        .quad   0x079c170bd843b388
+
+        // 2^88 * 7 * G
+
+        .quad   0x0506ece464fa6fff
+        .quad   0xbee3431e6205e523
+        .quad   0x3579422451b8ea42
+        .quad   0x6dec05e34ac9fb00
+        .quad   0xcdd6cd50c0d5d056
+        .quad   0x9af7686dbb03573b
+        .quad   0x3ca6723ff3c3ef48
+        .quad   0x6768c0d7317b8acc
+        .quad   0x94b625e5f155c1b3
+        .quad   0x417bf3a7997b7b91
+        .quad   0xc22cbddc6d6b2600
+        .quad   0x51445e14ddcd52f4
+
+        // 2^88 * 8 * G
+
+        .quad   0x57502b4b3b144951
+        .quad   0x8e67ff6b444bbcb3
+        .quad   0xb8bd6927166385db
+        .quad   0x13186f31e39295c8
+        .quad   0x893147ab2bbea455
+        .quad   0x8c53a24f92079129
+        .quad   0x4b49f948be30f7a7
+        .quad   0x12e990086e4fd43d
+        .quad   0xf10c96b37fdfbb2e
+        .quad   0x9f9a935e121ceaf9
+        .quad   0xdf1136c43a5b983f
+        .quad   0x77b2e3f05d3e99af
+
+        // 2^92 * 1 * G
+
+        .quad   0xfd0d75879cf12657
+        .quad   0xe82fef94e53a0e29
+        .quad   0xcc34a7f05bbb4be7
+        .quad   0x0b251172a50c38a2
+        .quad   0x9532f48fcc5cd29b
+        .quad   0x2ba851bea3ce3671
+        .quad   0x32dacaa051122941
+        .quad   0x478d99d9350004f2
+        .quad   0x1d5ad94890bb02c0
+        .quad   0x50e208b10ec25115
+        .quad   0xa26a22894ef21702
+        .quad   0x4dc923343b524805
+
+        // 2^92 * 2 * G
+
+        .quad   0xe3828c400f8086b6
+        .quad   0x3f77e6f7979f0dc8
+        .quad   0x7ef6de304df42cb4
+        .quad   0x5265797cb6abd784
+        .quad   0x3ad3e3ebf36c4975
+        .quad   0xd75d25a537862125
+        .quad   0xe873943da025a516
+        .quad   0x6bbc7cb4c411c847
+        .quad   0x3c6f9cd1d4a50d56
+        .quad   0xb6244077c6feab7e
+        .quad   0x6ff9bf483580972e
+        .quad   0x00375883b332acfb
+
+        // 2^92 * 3 * G
+
+        .quad   0x0001b2cd28cb0940
+        .quad   0x63fb51a06f1c24c9
+        .quad   0xb5ad8691dcd5ca31
+        .quad   0x67238dbd8c450660
+        .quad   0xc98bec856c75c99c
+        .quad   0xe44184c000e33cf4
+        .quad   0x0a676b9bba907634
+        .quad   0x669e2cb571f379d7
+        .quad   0xcb116b73a49bd308
+        .quad   0x025aad6b2392729e
+        .quad   0xb4793efa3f55d9b1
+        .quad   0x72a1056140678bb9
+
+        // 2^92 * 4 * G
+
+        .quad   0xa2b6812b1cc9249d
+        .quad   0x62866eee21211f58
+        .quad   0x2cb5c5b85df10ece
+        .quad   0x03a6b259e263ae00
+        .quad   0x0d8d2909e2e505b6
+        .quad   0x98ca78abc0291230
+        .quad   0x77ef5569a9b12327
+        .quad   0x7c77897b81439b47
+        .quad   0xf1c1b5e2de331cb5
+        .quad   0x5a9f5d8e15fca420
+        .quad   0x9fa438f17bd932b1
+        .quad   0x2a381bf01c6146e7
+
+        // 2^92 * 5 * G
+
+        .quad   0xac9b9879cfc811c1
+        .quad   0x8b7d29813756e567
+        .quad   0x50da4e607c70edfc
+        .quad   0x5dbca62f884400b6
+        .quad   0xf7c0be32b534166f
+        .quad   0x27e6ca6419cf70d4
+        .quad   0x934df7d7a957a759
+        .quad   0x5701461dabdec2aa
+        .quad   0x2c6747402c915c25
+        .quad   0x1bdcd1a80b0d340a
+        .quad   0x5e5601bd07b43f5f
+        .quad   0x2555b4e05539a242
+
+        // 2^92 * 6 * G
+
+        .quad   0x6fc09f5266ddd216
+        .quad   0xdce560a7c8e37048
+        .quad   0xec65939da2df62fd
+        .quad   0x7a869ae7e52ed192
+        .quad   0x78409b1d87e463d4
+        .quad   0xad4da95acdfb639d
+        .quad   0xec28773755259b9c
+        .quad   0x69c806e9c31230ab
+        .quad   0x7b48f57414bb3f22
+        .quad   0x68c7cee4aedccc88
+        .quad   0xed2f936179ed80be
+        .quad   0x25d70b885f77bc4b
+
+        // 2^92 * 7 * G
+
+        .quad   0x4151c3d9762bf4de
+        .quad   0x083f435f2745d82b
+        .quad   0x29775a2e0d23ddd5
+        .quad   0x138e3a6269a5db24
+        .quad   0x98459d29bb1ae4d4
+        .quad   0x56b9c4c739f954ec
+        .quad   0x832743f6c29b4b3e
+        .quad   0x21ea8e2798b6878a
+        .quad   0x87bef4b46a5a7b9c
+        .quad   0xd2299d1b5fc1d062
+        .quad   0x82409818dd321648
+        .quad   0x5c5abeb1e5a2e03d
+
+        // 2^92 * 8 * G
+
+        .quad   0x14722af4b73c2ddb
+        .quad   0xbc470c5f5a05060d
+        .quad   0x00943eac2581b02e
+        .quad   0x0e434b3b1f499c8f
+        .quad   0x02cde6de1306a233
+        .quad   0x7b5a52a2116f8ec7
+        .quad   0xe1c681f4c1163b5b
+        .quad   0x241d350660d32643
+        .quad   0x6be4404d0ebc52c7
+        .quad   0xae46233bb1a791f5
+        .quad   0x2aec170ed25db42b
+        .quad   0x1d8dfd966645d694
+
+        // 2^96 * 1 * G
+
+        .quad   0x296fa9c59c2ec4de
+        .quad   0xbc8b61bf4f84f3cb
+        .quad   0x1c7706d917a8f908
+        .quad   0x63b795fc7ad3255d
+        .quad   0xd598639c12ddb0a4
+        .quad   0xa5d19f30c024866b
+        .quad   0xd17c2f0358fce460
+        .quad   0x07a195152e095e8a
+        .quad   0xa8368f02389e5fc8
+        .quad   0x90433b02cf8de43b
+        .quad   0xafa1fd5dc5412643
+        .quad   0x3e8fe83d032f0137
+
+        // 2^96 * 2 * G
+
+        .quad   0x2f8b15b90570a294
+        .quad   0x94f2427067084549
+        .quad   0xde1c5ae161bbfd84
+        .quad   0x75ba3b797fac4007
+        .quad   0x08704c8de8efd13c
+        .quad   0xdfc51a8e33e03731
+        .quad   0xa59d5da51260cde3
+        .quad   0x22d60899a6258c86
+        .quad   0x6239dbc070cdd196
+        .quad   0x60fe8a8b6c7d8a9a
+        .quad   0xb38847bceb401260
+        .quad   0x0904d07b87779e5e
+
+        // 2^96 * 3 * G
+
+        .quad   0xb4ce1fd4ddba919c
+        .quad   0xcf31db3ec74c8daa
+        .quad   0x2c63cc63ad86cc51
+        .quad   0x43e2143fbc1dde07
+        .quad   0xf4322d6648f940b9
+        .quad   0x06952f0cbd2d0c39
+        .quad   0x167697ada081f931
+        .quad   0x6240aacebaf72a6c
+        .quad   0xf834749c5ba295a0
+        .quad   0xd6947c5bca37d25a
+        .quad   0x66f13ba7e7c9316a
+        .quad   0x56bdaf238db40cac
+
+        // 2^96 * 4 * G
+
+        .quad   0x362ab9e3f53533eb
+        .quad   0x338568d56eb93d40
+        .quad   0x9e0e14521d5a5572
+        .quad   0x1d24a86d83741318
+        .quad   0x1310d36cc19d3bb2
+        .quad   0x062a6bb7622386b9
+        .quad   0x7c9b8591d7a14f5c
+        .quad   0x03aa31507e1e5754
+        .quad   0xf4ec7648ffd4ce1f
+        .quad   0xe045eaf054ac8c1c
+        .quad   0x88d225821d09357c
+        .quad   0x43b261dc9aeb4859
+
+        // 2^96 * 5 * G
+
+        .quad   0xe55b1e1988bb79bb
+        .quad   0xa09ed07dc17a359d
+        .quad   0xb02c2ee2603dea33
+        .quad   0x326055cf5b276bc2
+        .quad   0x19513d8b6c951364
+        .quad   0x94fe7126000bf47b
+        .quad   0x028d10ddd54f9567
+        .quad   0x02b4d5e242940964
+        .quad   0xb4a155cb28d18df2
+        .quad   0xeacc4646186ce508
+        .quad   0xc49cf4936c824389
+        .quad   0x27a6c809ae5d3410
+
+        // 2^96 * 6 * G
+
+        .quad   0x8ba6ebcd1f0db188
+        .quad   0x37d3d73a675a5be8
+        .quad   0xf22edfa315f5585a
+        .quad   0x2cb67174ff60a17e
+        .quad   0xcd2c270ac43d6954
+        .quad   0xdd4a3e576a66cab2
+        .quad   0x79fa592469d7036c
+        .quad   0x221503603d8c2599
+        .quad   0x59eecdf9390be1d0
+        .quad   0xa9422044728ce3f1
+        .quad   0x82891c667a94f0f4
+        .quad   0x7b1df4b73890f436
+
+        // 2^96 * 7 * G
+
+        .quad   0xe492f2e0b3b2a224
+        .quad   0x7c6c9e062b551160
+        .quad   0x15eb8fe20d7f7b0e
+        .quad   0x61fcef2658fc5992
+        .quad   0x5f2e221807f8f58c
+        .quad   0xe3555c9fd49409d4
+        .quad   0xb2aaa88d1fb6a630
+        .quad   0x68698245d352e03d
+        .quad   0xdbb15d852a18187a
+        .quad   0xf3e4aad386ddacd7
+        .quad   0x44bae2810ff6c482
+        .quad   0x46cf4c473daf01cf
+
+        // 2^96 * 8 * G
+
+        .quad   0x426525ed9ec4e5f9
+        .quad   0x0e5eda0116903303
+        .quad   0x72b1a7f2cbe5cadc
+        .quad   0x29387bcd14eb5f40
+        .quad   0x213c6ea7f1498140
+        .quad   0x7c1e7ef8392b4854
+        .quad   0x2488c38c5629ceba
+        .quad   0x1065aae50d8cc5bb
+        .quad   0x1c2c4525df200d57
+        .quad   0x5c3b2dd6bfca674a
+        .quad   0x0a07e7b1e1834030
+        .quad   0x69a198e64f1ce716
+
+        // 2^100 * 1 * G
+
+        .quad   0x7afcd613efa9d697
+        .quad   0x0cc45aa41c067959
+        .quad   0xa56fe104c1fada96
+        .quad   0x3a73b70472e40365
+        .quad   0x7b26e56b9e2d4734
+        .quad   0xc4c7132b81c61675
+        .quad   0xef5c9525ec9cde7f
+        .quad   0x39c80b16e71743ad
+        .quad   0x0f196e0d1b826c68
+        .quad   0xf71ff0e24960e3db
+        .quad   0x6113167023b7436c
+        .quad   0x0cf0ea5877da7282
+
+        // 2^100 * 2 * G
+
+        .quad   0x196c80a4ddd4ccbd
+        .quad   0x22e6f55d95f2dd9d
+        .quad   0xc75e33c740d6c71b
+        .quad   0x7bb51279cb3c042f
+        .quad   0xe332ced43ba6945a
+        .quad   0xde0b1361e881c05d
+        .quad   0x1ad40f095e67ed3b
+        .quad   0x5da8acdab8c63d5d
+        .quad   0xc4b6664a3a70159f
+        .quad   0x76194f0f0a904e14
+        .quad   0xa5614c39a4096c13
+        .quad   0x6cd0ff50979feced
+
+        // 2^100 * 3 * G
+
+        .quad   0xc0e067e78f4428ac
+        .quad   0x14835ab0a61135e3
+        .quad   0xf21d14f338062935
+        .quad   0x6390a4c8df04849c
+        .quad   0x7fecfabdb04ba18e
+        .quad   0xd0fc7bfc3bddbcf7
+        .quad   0xa41d486e057a131c
+        .quad   0x641a4391f2223a61
+        .quad   0xc5c6b95aa606a8db
+        .quad   0x914b7f9eb06825f1
+        .quad   0x2a731f6b44fc9eff
+        .quad   0x30ddf38562705cfc
+
+        // 2^100 * 4 * G
+
+        .quad   0x4e3dcbdad1bff7f9
+        .quad   0xc9118e8220645717
+        .quad   0xbacccebc0f189d56
+        .quad   0x1b4822e9d4467668
+        .quad   0x33bef2bd68bcd52c
+        .quad   0xc649dbb069482ef2
+        .quad   0xb5b6ee0c41cb1aee
+        .quad   0x5c294d270212a7e5
+        .quad   0xab360a7f25563781
+        .quad   0x2512228a480f7958
+        .quad   0xc75d05276114b4e3
+        .quad   0x222d9625d976fe2a
+
+        // 2^100 * 5 * G
+
+        .quad   0x1c717f85b372ace1
+        .quad   0x81930e694638bf18
+        .quad   0x239cad056bc08b58
+        .quad   0x0b34271c87f8fff4
+        .quad   0x0f94be7e0a344f85
+        .quad   0xeb2faa8c87f22c38
+        .quad   0x9ce1e75e4ee16f0f
+        .quad   0x43e64e5418a08dea
+        .quad   0x8155e2521a35ce63
+        .quad   0xbe100d4df912028e
+        .quad   0xbff80bf8a57ddcec
+        .quad   0x57342dc96d6bc6e4
+
+        // 2^100 * 6 * G
+
+        .quad   0xefeef065c8ce5998
+        .quad   0xbf029510b5cbeaa2
+        .quad   0x8c64a10620b7c458
+        .quad   0x35134fb231c24855
+        .quad   0xf3c3bcb71e707bf6
+        .quad   0x351d9b8c7291a762
+        .quad   0x00502e6edad69a33
+        .quad   0x522f521f1ec8807f
+        .quad   0x272c1f46f9a3902b
+        .quad   0xc91ba3b799657bcc
+        .quad   0xae614b304f8a1c0e
+        .quad   0x7afcaad70b99017b
+
+        // 2^100 * 7 * G
+
+        .quad   0xc25ded54a4b8be41
+        .quad   0x902d13e11bb0e2dd
+        .quad   0x41f43233cde82ab2
+        .quad   0x1085faa5c3aae7cb
+        .quad   0xa88141ecef842b6b
+        .quad   0x55e7b14797abe6c5
+        .quad   0x8c748f9703784ffe
+        .quad   0x5b50a1f7afcd00b7
+        .quad   0x9b840f66f1361315
+        .quad   0x18462242701003e9
+        .quad   0x65ed45fae4a25080
+        .quad   0x0a2862393fda7320
+
+        // 2^100 * 8 * G
+
+        .quad   0x46ab13c8347cbc9d
+        .quad   0x3849e8d499c12383
+        .quad   0x4cea314087d64ac9
+        .quad   0x1f354134b1a29ee7
+        .quad   0x960e737b6ecb9d17
+        .quad   0xfaf24948d67ceae1
+        .quad   0x37e7a9b4d55e1b89
+        .quad   0x5cb7173cb46c59eb
+        .quad   0x4a89e68b82b7abf0
+        .quad   0xf41cd9279ba6b7b9
+        .quad   0x16e6c210e18d876f
+        .quad   0x7cacdb0f7f1b09c6
+
+        // 2^104 * 1 * G
+
+        .quad   0x9062b2e0d91a78bc
+        .quad   0x47c9889cc8509667
+        .quad   0x9df54a66405070b8
+        .quad   0x7369e6a92493a1bf
+        .quad   0xe1014434dcc5caed
+        .quad   0x47ed5d963c84fb33
+        .quad   0x70019576ed86a0e7
+        .quad   0x25b2697bd267f9e4
+        .quad   0x9d673ffb13986864
+        .quad   0x3ca5fbd9415dc7b8
+        .quad   0xe04ecc3bdf273b5e
+        .quad   0x1420683db54e4cd2
+
+        // 2^104 * 2 * G
+
+        .quad   0xb478bd1e249dd197
+        .quad   0x620c35005e58c102
+        .quad   0xfb02d32fccbaac5c
+        .quad   0x60b63bebf508a72d
+        .quad   0x34eebb6fc1cc5ad0
+        .quad   0x6a1b0ce99646ac8b
+        .quad   0xd3b0da49a66bde53
+        .quad   0x31e83b4161d081c1
+        .quad   0x97e8c7129e062b4f
+        .quad   0x49e48f4f29320ad8
+        .quad   0x5bece14b6f18683f
+        .quad   0x55cf1eb62d550317
+
+        // 2^104 * 3 * G
+
+        .quad   0x5879101065c23d58
+        .quad   0x8b9d086d5094819c
+        .quad   0xe2402fa912c55fa7
+        .quad   0x669a6564570891d4
+        .quad   0x3076b5e37df58c52
+        .quad   0xd73ab9dde799cc36
+        .quad   0xbd831ce34913ee20
+        .quad   0x1a56fbaa62ba0133
+        .quad   0x943e6b505c9dc9ec
+        .quad   0x302557bba77c371a
+        .quad   0x9873ae5641347651
+        .quad   0x13c4836799c58a5c
+
+        // 2^104 * 4 * G
+
+        .quad   0x423a5d465ab3e1b9
+        .quad   0xfc13c187c7f13f61
+        .quad   0x19f83664ecb5b9b6
+        .quad   0x66f80c93a637b607
+        .quad   0xc4dcfb6a5d8bd080
+        .quad   0xdeebc4ec571a4842
+        .quad   0xd4b2e883b8e55365
+        .quad   0x50bdc87dc8e5b827
+        .quad   0x606d37836edfe111
+        .quad   0x32353e15f011abd9
+        .quad   0x64b03ac325b73b96
+        .quad   0x1dd56444725fd5ae
+
+        // 2^104 * 5 * G
+
+        .quad   0x8fa47ff83362127d
+        .quad   0xbc9f6ac471cd7c15
+        .quad   0x6e71454349220c8b
+        .quad   0x0e645912219f732e
+        .quad   0xc297e60008bac89a
+        .quad   0x7d4cea11eae1c3e0
+        .quad   0xf3e38be19fe7977c
+        .quad   0x3a3a450f63a305cd
+        .quad   0x078f2f31d8394627
+        .quad   0x389d3183de94a510
+        .quad   0xd1e36c6d17996f80
+        .quad   0x318c8d9393a9a87b
+
+        // 2^104 * 6 * G
+
+        .quad   0xf2745d032afffe19
+        .quad   0x0c9f3c497f24db66
+        .quad   0xbc98d3e3ba8598ef
+        .quad   0x224c7c679a1d5314
+        .quad   0x5d669e29ab1dd398
+        .quad   0xfc921658342d9e3b
+        .quad   0x55851dfdf35973cd
+        .quad   0x509a41c325950af6
+        .quad   0xbdc06edca6f925e9
+        .quad   0x793ef3f4641b1f33
+        .quad   0x82ec12809d833e89
+        .quad   0x05bff02328a11389
+
+        // 2^104 * 7 * G
+
+        .quad   0x3632137023cae00b
+        .quad   0x544acf0ad1accf59
+        .quad   0x96741049d21a1c88
+        .quad   0x780b8cc3fa2a44a7
+        .quad   0x6881a0dd0dc512e4
+        .quad   0x4fe70dc844a5fafe
+        .quad   0x1f748e6b8f4a5240
+        .quad   0x576277cdee01a3ea
+        .quad   0x1ef38abc234f305f
+        .quad   0x9a577fbd1405de08
+        .quad   0x5e82a51434e62a0d
+        .quad   0x5ff418726271b7a1
+
+        // 2^104 * 8 * G
+
+        .quad   0x398e080c1789db9d
+        .quad   0xa7602025f3e778f5
+        .quad   0xfa98894c06bd035d
+        .quad   0x106a03dc25a966be
+        .quad   0xe5db47e813b69540
+        .quad   0xf35d2a3b432610e1
+        .quad   0xac1f26e938781276
+        .quad   0x29d4db8ca0a0cb69
+        .quad   0xd9ad0aaf333353d0
+        .quad   0x38669da5acd309e5
+        .quad   0x3c57658ac888f7f0
+        .quad   0x4ab38a51052cbefa
+
+        // 2^108 * 1 * G
+
+        .quad   0xdfdacbee4324c0e9
+        .quad   0x054442883f955bb7
+        .quad   0xdef7aaa8ea31609f
+        .quad   0x68aee70642287cff
+        .quad   0xf68fe2e8809de054
+        .quad   0xe3bc096a9c82bad1
+        .quad   0x076353d40aadbf45
+        .quad   0x7b9b1fb5dea1959e
+        .quad   0xf01cc8f17471cc0c
+        .quad   0x95242e37579082bb
+        .quad   0x27776093d3e46b5f
+        .quad   0x2d13d55a28bd85fb
+
+        // 2^108 * 2 * G
+
+        .quad   0xfac5d2065b35b8da
+        .quad   0xa8da8a9a85624bb7
+        .quad   0xccd2ca913d21cd0f
+        .quad   0x6b8341ee8bf90d58
+        .quad   0xbf019cce7aee7a52
+        .quad   0xa8ded2b6e454ead3
+        .quad   0x3c619f0b87a8bb19
+        .quad   0x3619b5d7560916d8
+        .quad   0x3579f26b0282c4b2
+        .quad   0x64d592f24fafefae
+        .quad   0xb7cded7b28c8c7c0
+        .quad   0x6a927b6b7173a8d7
+
+        // 2^108 * 3 * G
+
+        .quad   0x1f6db24f986e4656
+        .quad   0x1021c02ed1e9105b
+        .quad   0xf8ff3fff2cc0a375
+        .quad   0x1d2a6bf8c6c82592
+        .quad   0x8d7040863ece88eb
+        .quad   0xf0e307a980eec08c
+        .quad   0xac2250610d788fda
+        .quad   0x056d92a43a0d478d
+        .quad   0x1b05a196fc3da5a1
+        .quad   0x77d7a8c243b59ed0
+        .quad   0x06da3d6297d17918
+        .quad   0x66fbb494f12353f7
+
+        // 2^108 * 4 * G
+
+        .quad   0x751a50b9d85c0fb8
+        .quad   0xd1afdc258bcf097b
+        .quad   0x2f16a6a38309a969
+        .quad   0x14ddff9ee5b00659
+        .quad   0xd6d70996f12309d6
+        .quad   0xdbfb2385e9c3d539
+        .quad   0x46d602b0f7552411
+        .quad   0x270a0b0557843e0c
+        .quad   0x61ff0640a7862bcc
+        .quad   0x81cac09a5f11abfe
+        .quad   0x9047830455d12abb
+        .quad   0x19a4bde1945ae873
+
+        // 2^108 * 5 * G
+
+        .quad   0x9b9f26f520a6200a
+        .quad   0x64804443cf13eaf8
+        .quad   0x8a63673f8631edd3
+        .quad   0x72bbbce11ed39dc1
+        .quad   0x40c709dec076c49f
+        .quad   0x657bfaf27f3e53f6
+        .quad   0x40662331eca042c4
+        .quad   0x14b375487eb4df04
+        .quad   0xae853c94ab66dc47
+        .quad   0xeb62343edf762d6e
+        .quad   0xf08e0e186fb2f7d1
+        .quad   0x4f0b1c02700ab37a
+
+        // 2^108 * 6 * G
+
+        .quad   0xe1706787d81951fa
+        .quad   0xa10a2c8eb290c77b
+        .quad   0xe7382fa03ed66773
+        .quad   0x0a4d84710bcc4b54
+        .quad   0x79fd21ccc1b2e23f
+        .quad   0x4ae7c281453df52a
+        .quad   0xc8172ec9d151486b
+        .quad   0x68abe9443e0a7534
+        .quad   0xda12c6c407831dcb
+        .quad   0x0da230d74d5c510d
+        .quad   0x4ab1531e6bd404e1
+        .quad   0x4106b166bcf440ef
+
+        // 2^108 * 7 * G
+
+        .quad   0x02e57a421cd23668
+        .quad   0x4ad9fb5d0eaef6fd
+        .quad   0x954e6727b1244480
+        .quad   0x7f792f9d2699f331
+        .quad   0xa485ccd539e4ecf2
+        .quad   0x5aa3f3ad0555bab5
+        .quad   0x145e3439937df82d
+        .quad   0x1238b51e1214283f
+        .quad   0x0b886b925fd4d924
+        .quad   0x60906f7a3626a80d
+        .quad   0xecd367b4b98abd12
+        .quad   0x2876beb1def344cf
+
+        // 2^108 * 8 * G
+
+        .quad   0xdc84e93563144691
+        .quad   0x632fe8a0d61f23f4
+        .quad   0x4caa800612a9a8d5
+        .quad   0x48f9dbfa0e9918d3
+        .quad   0xd594b3333a8a85f8
+        .quad   0x4ea37689e78d7d58
+        .quad   0x73bf9f455e8e351f
+        .quad   0x5507d7d2bc41ebb4
+        .quad   0x1ceb2903299572fc
+        .quad   0x7c8ccaa29502d0ee
+        .quad   0x91bfa43411cce67b
+        .quad   0x5784481964a831e7
+
+        // 2^112 * 1 * G
+
+        .quad   0xda7c2b256768d593
+        .quad   0x98c1c0574422ca13
+        .quad   0xf1a80bd5ca0ace1d
+        .quad   0x29cdd1adc088a690
+        .quad   0xd6cfd1ef5fddc09c
+        .quad   0xe82b3efdf7575dce
+        .quad   0x25d56b5d201634c2
+        .quad   0x3041c6bb04ed2b9b
+        .quad   0x0ff2f2f9d956e148
+        .quad   0xade797759f356b2e
+        .quad   0x1a4698bb5f6c025c
+        .quad   0x104bbd6814049a7b
+
+        // 2^112 * 2 * G
+
+        .quad   0x51f0fd3168f1ed67
+        .quad   0x2c811dcdd86f3bc2
+        .quad   0x44dc5c4304d2f2de
+        .quad   0x5be8cc57092a7149
+        .quad   0xa95d9a5fd67ff163
+        .quad   0xe92be69d4cc75681
+        .quad   0xb7f8024cde20f257
+        .quad   0x204f2a20fb072df5
+        .quad   0xc8143b3d30ebb079
+        .quad   0x7589155abd652e30
+        .quad   0x653c3c318f6d5c31
+        .quad   0x2570fb17c279161f
+
+        // 2^112 * 3 * G
+
+        .quad   0x3efa367f2cb61575
+        .quad   0xf5f96f761cd6026c
+        .quad   0xe8c7142a65b52562
+        .quad   0x3dcb65ea53030acd
+        .quad   0x192ea9550bb8245a
+        .quad   0xc8e6fba88f9050d1
+        .quad   0x7986ea2d88a4c935
+        .quad   0x241c5f91de018668
+        .quad   0x28d8172940de6caa
+        .quad   0x8fbf2cf022d9733a
+        .quad   0x16d7fcdd235b01d1
+        .quad   0x08420edd5fcdf0e5
+
+        // 2^112 * 4 * G
+
+        .quad   0xcdff20ab8362fa4a
+        .quad   0x57e118d4e21a3e6e
+        .quad   0xe3179617fc39e62b
+        .quad   0x0d9a53efbc1769fd
+        .quad   0x0358c34e04f410ce
+        .quad   0xb6135b5a276e0685
+        .quad   0x5d9670c7ebb91521
+        .quad   0x04d654f321db889c
+        .quad   0x5e7dc116ddbdb5d5
+        .quad   0x2954deb68da5dd2d
+        .quad   0x1cb608173334a292
+        .quad   0x4a7a4f2618991ad7
+
+        // 2^112 * 5 * G
+
+        .quad   0xf4a718025fb15f95
+        .quad   0x3df65f346b5c1b8f
+        .quad   0xcdfcf08500e01112
+        .quad   0x11b50c4cddd31848
+        .quad   0x24c3b291af372a4b
+        .quad   0x93da8270718147f2
+        .quad   0xdd84856486899ef2
+        .quad   0x4a96314223e0ee33
+        .quad   0xa6e8274408a4ffd6
+        .quad   0x738e177e9c1576d9
+        .quad   0x773348b63d02b3f2
+        .quad   0x4f4bce4dce6bcc51
+
+        // 2^112 * 6 * G
+
+        .quad   0xa71fce5ae2242584
+        .quad   0x26ea725692f58a9e
+        .quad   0xd21a09d71cea3cf4
+        .quad   0x73fcdd14b71c01e6
+        .quad   0x30e2616ec49d0b6f
+        .quad   0xe456718fcaec2317
+        .quad   0x48eb409bf26b4fa6
+        .quad   0x3042cee561595f37
+        .quad   0x427e7079449bac41
+        .quad   0x855ae36dbce2310a
+        .quad   0x4cae76215f841a7c
+        .quad   0x389e740c9a9ce1d6
+
+        // 2^112 * 7 * G
+
+        .quad   0x64fcb3ae34dcb9ce
+        .quad   0x97500323e348d0ad
+        .quad   0x45b3f07d62c6381b
+        .quad   0x61545379465a6788
+        .quad   0xc9bd78f6570eac28
+        .quad   0xe55b0b3227919ce1
+        .quad   0x65fc3eaba19b91ed
+        .quad   0x25c425e5d6263690
+        .quad   0x3f3e06a6f1d7de6e
+        .quad   0x3ef976278e062308
+        .quad   0x8c14f6264e8a6c77
+        .quad   0x6539a08915484759
+
+        // 2^112 * 8 * G
+
+        .quad   0xe9d21f74c3d2f773
+        .quad   0xc150544125c46845
+        .quad   0x624e5ce8f9b99e33
+        .quad   0x11c5e4aac5cd186c
+        .quad   0xddc4dbd414bb4a19
+        .quad   0x19b2bc3c98424f8e
+        .quad   0x48a89fd736ca7169
+        .quad   0x0f65320ef019bd90
+        .quad   0xd486d1b1cafde0c6
+        .quad   0x4f3fe6e3163b5181
+        .quad   0x59a8af0dfaf2939a
+        .quad   0x4cabc7bdec33072a
+
+        // 2^116 * 1 * G
+
+        .quad   0x16faa8fb532f7428
+        .quad   0xdbd42ea046a4e272
+        .quad   0x5337653b8b9ea480
+        .quad   0x4065947223973f03
+        .quad   0xf7c0a19c1a54a044
+        .quad   0x4a1c5e2477bd9fbb
+        .quad   0xa6e3ca115af22972
+        .quad   0x1819bb953f2e9e0d
+        .quad   0x498fbb795e042e84
+        .quad   0x7d0dd89a7698b714
+        .quad   0x8bfb0ba427fe6295
+        .quad   0x36ba82e721200524
+
+        // 2^116 * 2 * G
+
+        .quad   0xd60ecbb74245ec41
+        .quad   0xfd9be89e34348716
+        .quad   0xc9240afee42284de
+        .quad   0x4472f648d0531db4
+        .quad   0xc8d69d0a57274ed5
+        .quad   0x45ba803260804b17
+        .quad   0xdf3cda102255dfac
+        .quad   0x77d221232709b339
+        .quad   0x498a6d7064ad94d8
+        .quad   0xa5b5c8fd9af62263
+        .quad   0x8ca8ed0545c141f4
+        .quad   0x2c63bec3662d358c
+
+        // 2^116 * 3 * G
+
+        .quad   0x7fe60d8bea787955
+        .quad   0xb9dc117eb5f401b7
+        .quad   0x91c7c09a19355cce
+        .quad   0x22692ef59442bedf
+        .quad   0x9a518b3a8586f8bf
+        .quad   0x9ee71af6cbb196f0
+        .quad   0xaa0625e6a2385cf2
+        .quad   0x1deb2176ddd7c8d1
+        .quad   0x8563d19a2066cf6c
+        .quad   0x401bfd8c4dcc7cd7
+        .quad   0xd976a6becd0d8f62
+        .quad   0x67cfd773a278b05e
+
+        // 2^116 * 4 * G
+
+        .quad   0x8dec31faef3ee475
+        .quad   0x99dbff8a9e22fd92
+        .quad   0x512d11594e26cab1
+        .quad   0x0cde561eec4310b9
+        .quad   0x2d5fa9855a4e586a
+        .quad   0x65f8f7a449beab7e
+        .quad   0xaa074dddf21d33d3
+        .quad   0x185cba721bcb9dee
+        .quad   0x93869da3f4e3cb41
+        .quad   0xbf0392f540f7977e
+        .quad   0x026204fcd0463b83
+        .quad   0x3ec91a769eec6eed
+
+        // 2^116 * 5 * G
+
+        .quad   0x1e9df75bf78166ad
+        .quad   0x4dfda838eb0cd7af
+        .quad   0xba002ed8c1eaf988
+        .quad   0x13fedb3e11f33cfc
+        .quad   0x0fad2fb7b0a3402f
+        .quad   0x46615ecbfb69f4a8
+        .quad   0xf745bcc8c5f8eaa6
+        .quad   0x7a5fa8794a94e896
+        .quad   0x52958faa13cd67a1
+        .quad   0x965ee0818bdbb517
+        .quad   0x16e58daa2e8845b3
+        .quad   0x357d397d5499da8f
+
+        // 2^116 * 6 * G
+
+        .quad   0x1ebfa05fb0bace6c
+        .quad   0xc934620c1caf9a1e
+        .quad   0xcc771cc41d82b61a
+        .quad   0x2d94a16aa5f74fec
+        .quad   0x481dacb4194bfbf8
+        .quad   0x4d77e3f1bae58299
+        .quad   0x1ef4612e7d1372a0
+        .quad   0x3a8d867e70ff69e1
+        .quad   0x6f58cd5d55aff958
+        .quad   0xba3eaa5c75567721
+        .quad   0x75c123999165227d
+        .quad   0x69be1343c2f2b35e
+
+        // 2^116 * 7 * G
+
+        .quad   0x0e091d5ee197c92a
+        .quad   0x4f51019f2945119f
+        .quad   0x143679b9f034e99c
+        .quad   0x7d88112e4d24c696
+        .quad   0x82bbbdac684b8de3
+        .quad   0xa2f4c7d03fca0718
+        .quad   0x337f92fbe096aaa8
+        .quad   0x200d4d8c63587376
+        .quad   0x208aed4b4893b32b
+        .quad   0x3efbf23ebe59b964
+        .quad   0xd762deb0dba5e507
+        .quad   0x69607bd681bd9d94
+
+        // 2^116 * 8 * G
+
+        .quad   0xf6be021068de1ce1
+        .quad   0xe8d518e70edcbc1f
+        .quad   0xe3effdd01b5505a5
+        .quad   0x35f63353d3ec3fd0
+        .quad   0x3b7f3bd49323a902
+        .quad   0x7c21b5566b2c6e53
+        .quad   0xe5ba8ff53a7852a7
+        .quad   0x28bc77a5838ece00
+        .quad   0x63ba78a8e25d8036
+        .quad   0x63651e0094333490
+        .quad   0x48d82f20288ce532
+        .quad   0x3a31abfa36b57524
+
+        // 2^120 * 1 * G
+
+        .quad   0x239e9624089c0a2e
+        .quad   0xc748c4c03afe4738
+        .quad   0x17dbed2a764fa12a
+        .quad   0x639b93f0321c8582
+        .quad   0xc08f788f3f78d289
+        .quad   0xfe30a72ca1404d9f
+        .quad   0xf2778bfccf65cc9d
+        .quad   0x7ee498165acb2021
+        .quad   0x7bd508e39111a1c3
+        .quad   0x2b2b90d480907489
+        .quad   0xe7d2aec2ae72fd19
+        .quad   0x0edf493c85b602a6
+
+        // 2^120 * 2 * G
+
+        .quad   0xaecc8158599b5a68
+        .quad   0xea574f0febade20e
+        .quad   0x4fe41d7422b67f07
+        .quad   0x403b92e3019d4fb4
+        .quad   0x6767c4d284764113
+        .quad   0xa090403ff7f5f835
+        .quad   0x1c8fcffacae6bede
+        .quad   0x04c00c54d1dfa369
+        .quad   0x4dc22f818b465cf8
+        .quad   0x71a0f35a1480eff8
+        .quad   0xaee8bfad04c7d657
+        .quad   0x355bb12ab26176f4
+
+        // 2^120 * 3 * G
+
+        .quad   0xa71e64cc7493bbf4
+        .quad   0xe5bd84d9eca3b0c3
+        .quad   0x0a6bc50cfa05e785
+        .quad   0x0f9b8132182ec312
+        .quad   0xa301dac75a8c7318
+        .quad   0xed90039db3ceaa11
+        .quad   0x6f077cbf3bae3f2d
+        .quad   0x7518eaf8e052ad8e
+        .quad   0xa48859c41b7f6c32
+        .quad   0x0f2d60bcf4383298
+        .quad   0x1815a929c9b1d1d9
+        .quad   0x47c3871bbb1755c4
+
+        // 2^120 * 4 * G
+
+        .quad   0x5144539771ec4f48
+        .quad   0xf805b17dc98c5d6e
+        .quad   0xf762c11a47c3c66b
+        .quad   0x00b89b85764699dc
+        .quad   0xfbe65d50c85066b0
+        .quad   0x62ecc4b0b3a299b0
+        .quad   0xe53754ea441ae8e0
+        .quad   0x08fea02ce8d48d5f
+        .quad   0x824ddd7668deead0
+        .quad   0xc86445204b685d23
+        .quad   0xb514cfcd5d89d665
+        .quad   0x473829a74f75d537
+
+        // 2^120 * 5 * G
+
+        .quad   0x82d2da754679c418
+        .quad   0xe63bd7d8b2618df0
+        .quad   0x355eef24ac47eb0a
+        .quad   0x2078684c4833c6b4
+        .quad   0x23d9533aad3902c9
+        .quad   0x64c2ddceef03588f
+        .quad   0x15257390cfe12fb4
+        .quad   0x6c668b4d44e4d390
+        .quad   0x3b48cf217a78820c
+        .quad   0xf76a0ab281273e97
+        .quad   0xa96c65a78c8eed7b
+        .quad   0x7411a6054f8a433f
+
+        // 2^120 * 6 * G
+
+        .quad   0x4d659d32b99dc86d
+        .quad   0x044cdc75603af115
+        .quad   0xb34c712cdcc2e488
+        .quad   0x7c136574fb8134ff
+        .quad   0x579ae53d18b175b4
+        .quad   0x68713159f392a102
+        .quad   0x8455ecba1eef35f5
+        .quad   0x1ec9a872458c398f
+        .quad   0xb8e6a4d400a2509b
+        .quad   0x9b81d7020bc882b4
+        .quad   0x57e7cc9bf1957561
+        .quad   0x3add88a5c7cd6460
+
+        // 2^120 * 7 * G
+
+        .quad   0xab895770b635dcf2
+        .quad   0x02dfef6cf66c1fbc
+        .quad   0x85530268beb6d187
+        .quad   0x249929fccc879e74
+        .quad   0x85c298d459393046
+        .quad   0x8f7e35985ff659ec
+        .quad   0x1d2ca22af2f66e3a
+        .quad   0x61ba1131a406a720
+        .quad   0xa3d0a0f116959029
+        .quad   0x023b6b6cba7ebd89
+        .quad   0x7bf15a3e26783307
+        .quad   0x5620310cbbd8ece7
+
+        // 2^120 * 8 * G
+
+        .quad   0x528993434934d643
+        .quad   0xb9dbf806a51222f5
+        .quad   0x8f6d878fc3f41c22
+        .quad   0x37676a2a4d9d9730
+        .quad   0x6646b5f477e285d6
+        .quad   0x40e8ff676c8f6193
+        .quad   0xa6ec7311abb594dd
+        .quad   0x7ec846f3658cec4d
+        .quad   0x9b5e8f3f1da22ec7
+        .quad   0x130f1d776c01cd13
+        .quad   0x214c8fcfa2989fb8
+        .quad   0x6daaf723399b9dd5
+
+        // 2^124 * 1 * G
+
+        .quad   0x591e4a5610628564
+        .quad   0x2a4bb87ca8b4df34
+        .quad   0xde2a2572e7a38e43
+        .quad   0x3cbdabd9fee5046e
+        .quad   0x81aebbdd2cd13070
+        .quad   0x962e4325f85a0e9e
+        .quad   0xde9391aacadffecb
+        .quad   0x53177fda52c230e6
+        .quad   0xa7bc970650b9de79
+        .quad   0x3d12a7fbc301b59b
+        .quad   0x02652e68d36ae38c
+        .quad   0x79d739835a6199dc
+
+        // 2^124 * 2 * G
+
+        .quad   0xd9354df64131c1bd
+        .quad   0x758094a186ec5822
+        .quad   0x4464ee12e459f3c2
+        .quad   0x6c11fce4cb133282
+        .quad   0x21c9d9920d591737
+        .quad   0x9bea41d2e9b46cd6
+        .quad   0xe20e84200d89bfca
+        .quad   0x79d99f946eae5ff8
+        .quad   0xf17b483568673205
+        .quad   0x387deae83caad96c
+        .quad   0x61b471fd56ffe386
+        .quad   0x31741195b745a599
+
+        // 2^124 * 3 * G
+
+        .quad   0xe8d10190b77a360b
+        .quad   0x99b983209995e702
+        .quad   0xbd4fdff8fa0247aa
+        .quad   0x2772e344e0d36a87
+        .quad   0x17f8ba683b02a047
+        .quad   0x50212096feefb6c8
+        .quad   0x70139be21556cbe2
+        .quad   0x203e44a11d98915b
+        .quad   0xd6863eba37b9e39f
+        .quad   0x105bc169723b5a23
+        .quad   0x104f6459a65c0762
+        .quad   0x567951295b4d38d4
+
+        // 2^124 * 4 * G
+
+        .quad   0x535fd60613037524
+        .quad   0xe210adf6b0fbc26a
+        .quad   0xac8d0a9b23e990ae
+        .quad   0x47204d08d72fdbf9
+        .quad   0x07242eb30d4b497f
+        .quad   0x1ef96306b9bccc87
+        .quad   0x37950934d8116f45
+        .quad   0x05468d6201405b04
+        .quad   0x00f565a9f93267de
+        .quad   0xcecfd78dc0d58e8a
+        .quad   0xa215e2dcf318e28e
+        .quad   0x4599ee919b633352
+
+        // 2^124 * 5 * G
+
+        .quad   0xd3c220ca70e0e76b
+        .quad   0xb12bea58ea9f3094
+        .quad   0x294ddec8c3271282
+        .quad   0x0c3539e1a1d1d028
+        .quad   0xac746d6b861ae579
+        .quad   0x31ab0650f6aea9dc
+        .quad   0x241d661140256d4c
+        .quad   0x2f485e853d21a5de
+        .quad   0x329744839c0833f3
+        .quad   0x6fe6257fd2abc484
+        .quad   0x5327d1814b358817
+        .quad   0x65712585893fe9bc
+
+        // 2^124 * 6 * G
+
+        .quad   0x9c102fb732a61161
+        .quad   0xe48e10dd34d520a8
+        .quad   0x365c63546f9a9176
+        .quad   0x32f6fe4c046f6006
+        .quad   0x81c29f1bd708ee3f
+        .quad   0xddcb5a05ae6407d0
+        .quad   0x97aec1d7d2a3eba7
+        .quad   0x1590521a91d50831
+        .quad   0x40a3a11ec7910acc
+        .quad   0x9013dff8f16d27ae
+        .quad   0x1a9720d8abb195d4
+        .quad   0x1bb9fe452ea98463
+
+        // 2^124 * 7 * G
+
+        .quad   0xe9d1d950b3d54f9e
+        .quad   0x2d5f9cbee00d33c1
+        .quad   0x51c2c656a04fc6ac
+        .quad   0x65c091ee3c1cbcc9
+        .quad   0xcf5e6c95cc36747c
+        .quad   0x294201536b0bc30d
+        .quad   0x453ac67cee797af0
+        .quad   0x5eae6ab32a8bb3c9
+        .quad   0x7083661114f118ea
+        .quad   0x2b37b87b94349cad
+        .quad   0x7273f51cb4e99f40
+        .quad   0x78a2a95823d75698
+
+        // 2^124 * 8 * G
+
+        .quad   0xa2b072e95c8c2ace
+        .quad   0x69cffc96651e9c4b
+        .quad   0x44328ef842e7b42b
+        .quad   0x5dd996c122aadeb3
+        .quad   0xb4f23c425ef83207
+        .quad   0xabf894d3c9a934b5
+        .quad   0xd0708c1339fd87f7
+        .quad   0x1876789117166130
+        .quad   0x925b5ef0670c507c
+        .quad   0x819bc842b93c33bf
+        .quad   0x10792e9a70dd003f
+        .quad   0x59ad4b7a6e28dc74
+
+        // 2^128 * 1 * G
+
+        .quad   0x5f3a7562eb3dbe47
+        .quad   0xf7ea38548ebda0b8
+        .quad   0x00c3e53145747299
+        .quad   0x1304e9e71627d551
+        .quad   0x583b04bfacad8ea2
+        .quad   0x29b743e8148be884
+        .quad   0x2b1e583b0810c5db
+        .quad   0x2b5449e58eb3bbaa
+        .quad   0x789814d26adc9cfe
+        .quad   0x3c1bab3f8b48dd0b
+        .quad   0xda0fe1fff979c60a
+        .quad   0x4468de2d7c2dd693
+
+        // 2^128 * 2 * G
+
+        .quad   0x51bb355e9419469e
+        .quad   0x33e6dc4c23ddc754
+        .quad   0x93a5b6d6447f9962
+        .quad   0x6cce7c6ffb44bd63
+        .quad   0x4b9ad8c6f86307ce
+        .quad   0x21113531435d0c28
+        .quad   0xd4a866c5657a772c
+        .quad   0x5da6427e63247352
+        .quad   0x1a94c688deac22ca
+        .quad   0xb9066ef7bbae1ff8
+        .quad   0x88ad8c388d59580f
+        .quad   0x58f29abfe79f2ca8
+
+        // 2^128 * 3 * G
+
+        .quad   0xe90ecfab8de73e68
+        .quad   0x54036f9f377e76a5
+        .quad   0xf0495b0bbe015982
+        .quad   0x577629c4a7f41e36
+        .quad   0x4b5a64bf710ecdf6
+        .quad   0xb14ce538462c293c
+        .quad   0x3643d056d50b3ab9
+        .quad   0x6af93724185b4870
+        .quad   0x3220024509c6a888
+        .quad   0xd2e036134b558973
+        .quad   0x83e236233c33289f
+        .quad   0x701f25bb0caec18f
+
+        // 2^128 * 4 * G
+
+        .quad   0xc3a8b0f8e4616ced
+        .quad   0xf700660e9e25a87d
+        .quad   0x61e3061ff4bca59c
+        .quad   0x2e0c92bfbdc40be9
+        .quad   0x9d18f6d97cbec113
+        .quad   0x844a06e674bfdbe4
+        .quad   0x20f5b522ac4e60d6
+        .quad   0x720a5bc050955e51
+        .quad   0x0c3f09439b805a35
+        .quad   0xe84e8b376242abfc
+        .quad   0x691417f35c229346
+        .quad   0x0e9b9cbb144ef0ec
+
+        // 2^128 * 5 * G
+
+        .quad   0xfbbad48ffb5720ad
+        .quad   0xee81916bdbf90d0e
+        .quad   0xd4813152635543bf
+        .quad   0x221104eb3f337bd8
+        .quad   0x8dee9bd55db1beee
+        .quad   0xc9c3ab370a723fb9
+        .quad   0x44a8f1bf1c68d791
+        .quad   0x366d44191cfd3cde
+        .quad   0x9e3c1743f2bc8c14
+        .quad   0x2eda26fcb5856c3b
+        .quad   0xccb82f0e68a7fb97
+        .quad   0x4167a4e6bc593244
+
+        // 2^128 * 6 * G
+
+        .quad   0x643b9d2876f62700
+        .quad   0x5d1d9d400e7668eb
+        .quad   0x1b4b430321fc0684
+        .quad   0x7938bb7e2255246a
+        .quad   0xc2be2665f8ce8fee
+        .quad   0xe967ff14e880d62c
+        .quad   0xf12e6e7e2f364eee
+        .quad   0x34b33370cb7ed2f6
+        .quad   0xcdc591ee8681d6cc
+        .quad   0xce02109ced85a753
+        .quad   0xed7485c158808883
+        .quad   0x1176fc6e2dfe65e4
+
+        // 2^128 * 7 * G
+
+        .quad   0xb4af6cd05b9c619b
+        .quad   0x2ddfc9f4b2a58480
+        .quad   0x3d4fa502ebe94dc4
+        .quad   0x08fc3a4c677d5f34
+        .quad   0xdb90e28949770eb8
+        .quad   0x98fbcc2aacf440a3
+        .quad   0x21354ffeded7879b
+        .quad   0x1f6a3e54f26906b6
+        .quad   0x60a4c199d30734ea
+        .quad   0x40c085b631165cd6
+        .quad   0xe2333e23f7598295
+        .quad   0x4f2fad0116b900d1
+
+        // 2^128 * 8 * G
+
+        .quad   0x44beb24194ae4e54
+        .quad   0x5f541c511857ef6c
+        .quad   0xa61e6b2d368d0498
+        .quad   0x445484a4972ef7ab
+        .quad   0x962cd91db73bb638
+        .quad   0xe60577aafc129c08
+        .quad   0x6f619b39f3b61689
+        .quad   0x3451995f2944ee81
+        .quad   0x9152fcd09fea7d7c
+        .quad   0x4a816c94b0935cf6
+        .quad   0x258e9aaa47285c40
+        .quad   0x10b89ca6042893b7
+
+        // 2^132 * 1 * G
+
+        .quad   0x9b2a426e3b646025
+        .quad   0x32127190385ce4cf
+        .quad   0xa25cffc2dd6dea45
+        .quad   0x06409010bea8de75
+        .quad   0xd67cded679d34aa0
+        .quad   0xcc0b9ec0cc4db39f
+        .quad   0xa535a456e35d190f
+        .quad   0x2e05d9eaf61f6fef
+        .quad   0xc447901ad61beb59
+        .quad   0x661f19bce5dc880a
+        .quad   0x24685482b7ca6827
+        .quad   0x293c778cefe07f26
+
+        // 2^132 * 2 * G
+
+        .quad   0x86809e7007069096
+        .quad   0xaad75b15e4e50189
+        .quad   0x07f35715a21a0147
+        .quad   0x0487f3f112815d5e
+        .quad   0x16c795d6a11ff200
+        .quad   0xcb70d0e2b15815c9
+        .quad   0x89f293209b5395b5
+        .quad   0x50b8c2d031e47b4f
+        .quad   0x48350c08068a4962
+        .quad   0x6ffdd05351092c9a
+        .quad   0x17af4f4aaf6fc8dd
+        .quad   0x4b0553b53cdba58b
+
+        // 2^132 * 3 * G
+
+        .quad   0x9c65fcbe1b32ff79
+        .quad   0xeb75ea9f03b50f9b
+        .quad   0xfced2a6c6c07e606
+        .quad   0x35106cd551717908
+        .quad   0xbf05211b27c152d4
+        .quad   0x5ec26849bd1af639
+        .quad   0x5e0b2caa8e6fab98
+        .quad   0x054c8bdd50bd0840
+        .quad   0x38a0b12f1dcf073d
+        .quad   0x4b60a8a3b7f6a276
+        .quad   0xfed5ac25d3404f9a
+        .quad   0x72e82d5e5505c229
+
+        // 2^132 * 4 * G
+
+        .quad   0x6b0b697ff0d844c8
+        .quad   0xbb12f85cd979cb49
+        .quad   0xd2a541c6c1da0f1f
+        .quad   0x7b7c242958ce7211
+        .quad   0x00d9cdfd69771d02
+        .quad   0x410276cd6cfbf17e
+        .quad   0x4c45306c1cb12ec7
+        .quad   0x2857bf1627500861
+        .quad   0x9f21903f0101689e
+        .quad   0xd779dfd3bf861005
+        .quad   0xa122ee5f3deb0f1b
+        .quad   0x510df84b485a00d4
+
+        // 2^132 * 5 * G
+
+        .quad   0xa54133bb9277a1fa
+        .quad   0x74ec3b6263991237
+        .quad   0x1a3c54dc35d2f15a
+        .quad   0x2d347144e482ba3a
+        .quad   0x24b3c887c70ac15e
+        .quad   0xb0f3a557fb81b732
+        .quad   0x9b2cde2fe578cc1b
+        .quad   0x4cf7ed0703b54f8e
+        .quad   0x6bd47c6598fbee0f
+        .quad   0x9e4733e2ab55be2d
+        .quad   0x1093f624127610c5
+        .quad   0x4e05e26ad0a1eaa4
+
+        // 2^132 * 6 * G
+
+        .quad   0xda9b6b624b531f20
+        .quad   0x429a760e77509abb
+        .quad   0xdbe9f522e823cb80
+        .quad   0x618f1856880c8f82
+        .quad   0x1833c773e18fe6c0
+        .quad   0xe3c4711ad3c87265
+        .quad   0x3bfd3c4f0116b283
+        .quad   0x1955875eb4cd4db8
+        .quad   0x6da6de8f0e399799
+        .quad   0x7ad61aa440fda178
+        .quad   0xb32cd8105e3563dd
+        .quad   0x15f6beae2ae340ae
+
+        // 2^132 * 7 * G
+
+        .quad   0x862bcb0c31ec3a62
+        .quad   0x810e2b451138f3c2
+        .quad   0x788ec4b839dac2a4
+        .quad   0x28f76867ae2a9281
+        .quad   0xba9a0f7b9245e215
+        .quad   0xf368612dd98c0dbb
+        .quad   0x2e84e4cbf220b020
+        .quad   0x6ba92fe962d90eda
+        .quad   0x3e4df9655884e2aa
+        .quad   0xbd62fbdbdbd465a5
+        .quad   0xd7596caa0de9e524
+        .quad   0x6e8042ccb2b1b3d7
+
+        // 2^132 * 8 * G
+
+        .quad   0xf10d3c29ce28ca6e
+        .quad   0xbad34540fcb6093d
+        .quad   0xe7426ed7a2ea2d3f
+        .quad   0x08af9d4e4ff298b9
+        .quad   0x1530653616521f7e
+        .quad   0x660d06b896203dba
+        .quad   0x2d3989bc545f0879
+        .quad   0x4b5303af78ebd7b0
+        .quad   0x72f8a6c3bebcbde8
+        .quad   0x4f0fca4adc3a8e89
+        .quad   0x6fa9d4e8c7bfdf7a
+        .quad   0x0dcf2d679b624eb7
+
+        // 2^136 * 1 * G
+
+        .quad   0x3d5947499718289c
+        .quad   0x12ebf8c524533f26
+        .quad   0x0262bfcb14c3ef15
+        .quad   0x20b878d577b7518e
+        .quad   0x753941be5a45f06e
+        .quad   0xd07caeed6d9c5f65
+        .quad   0x11776b9c72ff51b6
+        .quad   0x17d2d1d9ef0d4da9
+        .quad   0x27f2af18073f3e6a
+        .quad   0xfd3fe519d7521069
+        .quad   0x22e3b72c3ca60022
+        .quad   0x72214f63cc65c6a7
+
+        // 2^136 * 2 * G
+
+        .quad   0xb4e37f405307a693
+        .quad   0xaba714d72f336795
+        .quad   0xd6fbd0a773761099
+        .quad   0x5fdf48c58171cbc9
+        .quad   0x1d9db7b9f43b29c9
+        .quad   0xd605824a4f518f75
+        .quad   0xf2c072bd312f9dc4
+        .quad   0x1f24ac855a1545b0
+        .quad   0x24d608328e9505aa
+        .quad   0x4748c1d10c1420ee
+        .quad   0xc7ffe45c06fb25a2
+        .quad   0x00ba739e2ae395e6
+
+        // 2^136 * 3 * G
+
+        .quad   0x592e98de5c8790d6
+        .quad   0xe5bfb7d345c2a2df
+        .quad   0x115a3b60f9b49922
+        .quad   0x03283a3e67ad78f3
+        .quad   0xae4426f5ea88bb26
+        .quad   0x360679d984973bfb
+        .quad   0x5c9f030c26694e50
+        .quad   0x72297de7d518d226
+        .quad   0x48241dc7be0cb939
+        .quad   0x32f19b4d8b633080
+        .quad   0xd3dfc90d02289308
+        .quad   0x05e1296846271945
+
+        // 2^136 * 4 * G
+
+        .quad   0xba82eeb32d9c495a
+        .quad   0xceefc8fcf12bb97c
+        .quad   0xb02dabae93b5d1e0
+        .quad   0x39c00c9c13698d9b
+        .quad   0xadbfbbc8242c4550
+        .quad   0xbcc80cecd03081d9
+        .quad   0x843566a6f5c8df92
+        .quad   0x78cf25d38258ce4c
+        .quad   0x15ae6b8e31489d68
+        .quad   0xaa851cab9c2bf087
+        .quad   0xc9a75a97f04efa05
+        .quad   0x006b52076b3ff832
+
+        // 2^136 * 5 * G
+
+        .quad   0x29e0cfe19d95781c
+        .quad   0xb681df18966310e2
+        .quad   0x57df39d370516b39
+        .quad   0x4d57e3443bc76122
+        .quad   0xf5cb7e16b9ce082d
+        .quad   0x3407f14c417abc29
+        .quad   0xd4b36bce2bf4a7ab
+        .quad   0x7de2e9561a9f75ce
+        .quad   0xde70d4f4b6a55ecb
+        .quad   0x4801527f5d85db99
+        .quad   0xdbc9c440d3ee9a81
+        .quad   0x6b2a90af1a6029ed
+
+        // 2^136 * 6 * G
+
+        .quad   0x6923f4fc9ae61e97
+        .quad   0x5735281de03f5fd1
+        .quad   0xa764ae43e6edd12d
+        .quad   0x5fd8f4e9d12d3e4a
+        .quad   0x77ebf3245bb2d80a
+        .quad   0xd8301b472fb9079b
+        .quad   0xc647e6f24cee7333
+        .quad   0x465812c8276c2109
+        .quad   0x4d43beb22a1062d9
+        .quad   0x7065fb753831dc16
+        .quad   0x180d4a7bde2968d7
+        .quad   0x05b32c2b1cb16790
+
+        // 2^136 * 7 * G
+
+        .quad   0xc8c05eccd24da8fd
+        .quad   0xa1cf1aac05dfef83
+        .quad   0xdbbeeff27df9cd61
+        .quad   0x3b5556a37b471e99
+        .quad   0xf7fca42c7ad58195
+        .quad   0x3214286e4333f3cc
+        .quad   0xb6c29d0d340b979d
+        .quad   0x31771a48567307e1
+        .quad   0x32b0c524e14dd482
+        .quad   0xedb351541a2ba4b6
+        .quad   0xa3d16048282b5af3
+        .quad   0x4fc079d27a7336eb
+
+        // 2^136 * 8 * G
+
+        .quad   0x51c938b089bf2f7f
+        .quad   0x2497bd6502dfe9a7
+        .quad   0xffffc09c7880e453
+        .quad   0x124567cecaf98e92
+        .quad   0xdc348b440c86c50d
+        .quad   0x1337cbc9cc94e651
+        .quad   0x6422f74d643e3cb9
+        .quad   0x241170c2bae3cd08
+        .quad   0x3ff9ab860ac473b4
+        .quad   0xf0911dee0113e435
+        .quad   0x4ae75060ebc6c4af
+        .quad   0x3f8612966c87000d
+
+        // 2^140 * 1 * G
+
+        .quad   0x0c9c5303f7957be4
+        .quad   0xa3c31a20e085c145
+        .quad   0xb0721d71d0850050
+        .quad   0x0aba390eab0bf2da
+        .quad   0x529fdffe638c7bf3
+        .quad   0xdf2b9e60388b4995
+        .quad   0xe027b34f1bad0249
+        .quad   0x7bc92fc9b9fa74ed
+        .quad   0x9f97ef2e801ad9f9
+        .quad   0x83697d5479afda3a
+        .quad   0xe906b3ffbd596b50
+        .quad   0x02672b37dd3fb8e0
+
+        // 2^140 * 2 * G
+
+        .quad   0x48b2ca8b260885e4
+        .quad   0xa4286bec82b34c1c
+        .quad   0x937e1a2617f58f74
+        .quad   0x741d1fcbab2ca2a5
+        .quad   0xee9ba729398ca7f5
+        .quad   0xeb9ca6257a4849db
+        .quad   0x29eb29ce7ec544e1
+        .quad   0x232ca21ef736e2c8
+        .quad   0xbf61423d253fcb17
+        .quad   0x08803ceafa39eb14
+        .quad   0xf18602df9851c7af
+        .quad   0x0400f3a049e3414b
+
+        // 2^140 * 3 * G
+
+        .quad   0xabce0476ba61c55b
+        .quad   0x36a3d6d7c4d39716
+        .quad   0x6eb259d5e8d82d09
+        .quad   0x0c9176e984d756fb
+        .quad   0x2efba412a06e7b06
+        .quad   0x146785452c8d2560
+        .quad   0xdf9713ebd67a91c7
+        .quad   0x32830ac7157eadf3
+        .quad   0x0e782a7ab73769e8
+        .quad   0x04a05d7875b18e2c
+        .quad   0x29525226ebcceae1
+        .quad   0x0d794f8383eba820
+
+        // 2^140 * 4 * G
+
+        .quad   0xff35f5cb9e1516f4
+        .quad   0xee805bcf648aae45
+        .quad   0xf0d73c2bb93a9ef3
+        .quad   0x097b0bf22092a6c2
+        .quad   0x7be44ce7a7a2e1ac
+        .quad   0x411fd93efad1b8b7
+        .quad   0x1734a1d70d5f7c9b
+        .quad   0x0d6592233127db16
+        .quad   0xc48bab1521a9d733
+        .quad   0xa6c2eaead61abb25
+        .quad   0x625c6c1cc6cb4305
+        .quad   0x7fc90fea93eb3a67
+
+        // 2^140 * 5 * G
+
+        .quad   0x0408f1fe1f5c5926
+        .quad   0x1a8f2f5e3b258bf4
+        .quad   0x40a951a2fdc71669
+        .quad   0x6598ee93c98b577e
+        .quad   0xc527deb59c7cb23d
+        .quad   0x955391695328404e
+        .quad   0xd64392817ccf2c7a
+        .quad   0x6ce97dabf7d8fa11
+        .quad   0x25b5a8e50ef7c48f
+        .quad   0xeb6034116f2ce532
+        .quad   0xc5e75173e53de537
+        .quad   0x73119fa08c12bb03
+
+        // 2^140 * 6 * G
+
+        .quad   0xed30129453f1a4cb
+        .quad   0xbce621c9c8f53787
+        .quad   0xfacb2b1338bee7b9
+        .quad   0x3025798a9ea8428c
+        .quad   0x7845b94d21f4774d
+        .quad   0xbf62f16c7897b727
+        .quad   0x671857c03c56522b
+        .quad   0x3cd6a85295621212
+        .quad   0x3fecde923aeca999
+        .quad   0xbdaa5b0062e8c12f
+        .quad   0x67b99dfc96988ade
+        .quad   0x3f52c02852661036
+
+        // 2^140 * 7 * G
+
+        .quad   0xffeaa48e2a1351c6
+        .quad   0x28624754fa7f53d7
+        .quad   0x0b5ba9e57582ddf1
+        .quad   0x60c0104ba696ac59
+        .quad   0x9258bf99eec416c6
+        .quad   0xac8a5017a9d2f671
+        .quad   0x629549ab16dea4ab
+        .quad   0x05d0e85c99091569
+        .quad   0x051de020de9cbe97
+        .quad   0xfa07fc56b50bcf74
+        .quad   0x378cec9f0f11df65
+        .quad   0x36853c69ab96de4d
+
+        // 2^140 * 8 * G
+
+        .quad   0x36d9b8de78f39b2d
+        .quad   0x7f42ed71a847b9ec
+        .quad   0x241cd1d679bd3fde
+        .quad   0x6a704fec92fbce6b
+        .quad   0x4433c0b0fac5e7be
+        .quad   0x724bae854c08dcbe
+        .quad   0xf1f24cc446978f9b
+        .quad   0x4a0aff6d62825fc8
+        .quad   0xe917fb9e61095301
+        .quad   0xc102df9402a092f8
+        .quad   0xbf09e2f5fa66190b
+        .quad   0x681109bee0dcfe37
+
+        // 2^144 * 1 * G
+
+        .quad   0x559a0cc9782a0dde
+        .quad   0x551dcdb2ea718385
+        .quad   0x7f62865b31ef238c
+        .quad   0x504aa7767973613d
+        .quad   0x9c18fcfa36048d13
+        .quad   0x29159db373899ddd
+        .quad   0xdc9f350b9f92d0aa
+        .quad   0x26f57eee878a19d4
+        .quad   0x0cab2cd55687efb1
+        .quad   0x5180d162247af17b
+        .quad   0x85c15a344f5a2467
+        .quad   0x4041943d9dba3069
+
+        // 2^144 * 2 * G
+
+        .quad   0xc3c0eeba43ebcc96
+        .quad   0x8d749c9c26ea9caf
+        .quad   0xd9fa95ee1c77ccc6
+        .quad   0x1420a1d97684340f
+        .quad   0x4b217743a26caadd
+        .quad   0x47a6b424648ab7ce
+        .quad   0xcb1d4f7a03fbc9e3
+        .quad   0x12d931429800d019
+        .quad   0x00c67799d337594f
+        .quad   0x5e3c5140b23aa47b
+        .quad   0x44182854e35ff395
+        .quad   0x1b4f92314359a012
+
+        // 2^144 * 3 * G
+
+        .quad   0x3e5c109d89150951
+        .quad   0x39cefa912de9696a
+        .quad   0x20eae43f975f3020
+        .quad   0x239b572a7f132dae
+        .quad   0x33cf3030a49866b1
+        .quad   0x251f73d2215f4859
+        .quad   0xab82aa4051def4f6
+        .quad   0x5ff191d56f9a23f6
+        .quad   0x819ed433ac2d9068
+        .quad   0x2883ab795fc98523
+        .quad   0xef4572805593eb3d
+        .quad   0x020c526a758f36cb
+
+        // 2^144 * 4 * G
+
+        .quad   0x779834f89ed8dbbc
+        .quad   0xc8f2aaf9dc7ca46c
+        .quad   0xa9524cdca3e1b074
+        .quad   0x02aacc4615313877
+        .quad   0xe931ef59f042cc89
+        .quad   0x2c589c9d8e124bb6
+        .quad   0xadc8e18aaec75997
+        .quad   0x452cfe0a5602c50c
+        .quad   0x86a0f7a0647877df
+        .quad   0xbbc464270e607c9f
+        .quad   0xab17ea25f1fb11c9
+        .quad   0x4cfb7d7b304b877b
+
+        // 2^144 * 5 * G
+
+        .quad   0x72b43d6cb89b75fe
+        .quad   0x54c694d99c6adc80
+        .quad   0xb8c3aa373ee34c9f
+        .quad   0x14b4622b39075364
+        .quad   0xe28699c29789ef12
+        .quad   0x2b6ecd71df57190d
+        .quad   0xc343c857ecc970d0
+        .quad   0x5b1d4cbc434d3ac5
+        .quad   0xb6fb2615cc0a9f26
+        .quad   0x3a4f0e2bb88dcce5
+        .quad   0x1301498b3369a705
+        .quad   0x2f98f71258592dd1
+
+        // 2^144 * 6 * G
+
+        .quad   0x0c94a74cb50f9e56
+        .quad   0x5b1ff4a98e8e1320
+        .quad   0x9a2acc2182300f67
+        .quad   0x3a6ae249d806aaf9
+        .quad   0x2e12ae444f54a701
+        .quad   0xfcfe3ef0a9cbd7de
+        .quad   0xcebf890d75835de0
+        .quad   0x1d8062e9e7614554
+        .quad   0x657ada85a9907c5a
+        .quad   0x1a0ea8b591b90f62
+        .quad   0x8d0e1dfbdf34b4e9
+        .quad   0x298b8ce8aef25ff3
+
+        // 2^144 * 7 * G
+
+        .quad   0x2a927953eff70cb2
+        .quad   0x4b89c92a79157076
+        .quad   0x9418457a30a7cf6a
+        .quad   0x34b8a8404d5ce485
+        .quad   0x837a72ea0a2165de
+        .quad   0x3fab07b40bcf79f6
+        .quad   0x521636c77738ae70
+        .quad   0x6ba6271803a7d7dc
+        .quad   0xc26eecb583693335
+        .quad   0xd5a813df63b5fefd
+        .quad   0xa293aa9aa4b22573
+        .quad   0x71d62bdd465e1c6a
+
+        // 2^144 * 8 * G
+
+        .quad   0x6533cc28d378df80
+        .quad   0xf6db43790a0fa4b4
+        .quad   0xe3645ff9f701da5a
+        .quad   0x74d5f317f3172ba4
+        .quad   0xcd2db5dab1f75ef5
+        .quad   0xd77f95cf16b065f5
+        .quad   0x14571fea3f49f085
+        .quad   0x1c333621262b2b3d
+        .quad   0xa86fe55467d9ca81
+        .quad   0x398b7c752b298c37
+        .quad   0xda6d0892e3ac623b
+        .quad   0x4aebcc4547e9d98c
+
+        // 2^148 * 1 * G
+
+        .quad   0x53175a7205d21a77
+        .quad   0xb0c04422d3b934d4
+        .quad   0xadd9f24bdd5deadc
+        .quad   0x074f46e69f10ff8c
+        .quad   0x0de9b204a059a445
+        .quad   0xe15cb4aa4b17ad0f
+        .quad   0xe1bbec521f79c557
+        .quad   0x2633f1b9d071081b
+        .quad   0xc1fb4177018b9910
+        .quad   0xa6ea20dc6c0fe140
+        .quad   0xd661f3e74354c6ff
+        .quad   0x5ecb72e6f1a3407a
+
+        // 2^148 * 2 * G
+
+        .quad   0xa515a31b2259fb4e
+        .quad   0x0960f3972bcac52f
+        .quad   0xedb52fec8d3454cb
+        .quad   0x382e2720c476c019
+        .quad   0xfeeae106e8e86997
+        .quad   0x9863337f98d09383
+        .quad   0x9470480eaa06ebef
+        .quad   0x038b6898d4c5c2d0
+        .quad   0xf391c51d8ace50a6
+        .quad   0x3142d0b9ae2d2948
+        .quad   0xdb4d5a1a7f24ca80
+        .quad   0x21aeba8b59250ea8
+
+        // 2^148 * 3 * G
+
+        .quad   0x24f13b34cf405530
+        .quad   0x3c44ea4a43088af7
+        .quad   0x5dd5c5170006a482
+        .quad   0x118eb8f8890b086d
+        .quad   0x53853600f0087f23
+        .quad   0x4c461879da7d5784
+        .quad   0x6af303deb41f6860
+        .quad   0x0a3c16c5c27c18ed
+        .quad   0x17e49c17cc947f3d
+        .quad   0xccc6eda6aac1d27b
+        .quad   0xdf6092ceb0f08e56
+        .quad   0x4909b3e22c67c36b
+
+        // 2^148 * 4 * G
+
+        .quad   0x9c9c85ea63fe2e89
+        .quad   0xbe1baf910e9412ec
+        .quad   0x8f7baa8a86fbfe7b
+        .quad   0x0fb17f9fef968b6c
+        .quad   0x59a16676706ff64e
+        .quad   0x10b953dd0d86a53d
+        .quad   0x5848e1e6ce5c0b96
+        .quad   0x2d8b78e712780c68
+        .quad   0x79d5c62eafc3902b
+        .quad   0x773a215289e80728
+        .quad   0xc38ae640e10120b9
+        .quad   0x09ae23717b2b1a6d
+
+        // 2^148 * 5 * G
+
+        .quad   0xbb6a192a4e4d083c
+        .quad   0x34ace0630029e192
+        .quad   0x98245a59aafabaeb
+        .quad   0x6d9c8a9ada97faac
+        .quad   0x10ab8fa1ad32b1d0
+        .quad   0xe9aced1be2778b24
+        .quad   0xa8856bc0373de90f
+        .quad   0x66f35ddddda53996
+        .quad   0xd27d9afb24997323
+        .quad   0x1bb7e07ef6f01d2e
+        .quad   0x2ba7472df52ecc7f
+        .quad   0x03019b4f646f9dc8
+
+        // 2^148 * 6 * G
+
+        .quad   0x04a186b5565345cd
+        .quad   0xeee76610bcc4116a
+        .quad   0x689c73b478fb2a45
+        .quad   0x387dcbff65697512
+        .quad   0xaf09b214e6b3dc6b
+        .quad   0x3f7573b5ad7d2f65
+        .quad   0xd019d988100a23b0
+        .quad   0x392b63a58b5c35f7
+        .quad   0x4093addc9c07c205
+        .quad   0xc565be15f532c37e
+        .quad   0x63dbecfd1583402a
+        .quad   0x61722b4aef2e032e
+
+        // 2^148 * 7 * G
+
+        .quad   0x0012aafeecbd47af
+        .quad   0x55a266fb1cd46309
+        .quad   0xf203eb680967c72c
+        .quad   0x39633944ca3c1429
+        .quad   0xd6b07a5581cb0e3c
+        .quad   0x290ff006d9444969
+        .quad   0x08680b6a16dcda1f
+        .quad   0x5568d2b75a06de59
+        .quad   0x8d0cb88c1b37cfe1
+        .quad   0x05b6a5a3053818f3
+        .quad   0xf2e9bc04b787d959
+        .quad   0x6beba1249add7f64
+
+        // 2^148 * 8 * G
+
+        .quad   0x1d06005ca5b1b143
+        .quad   0x6d4c6bb87fd1cda2
+        .quad   0x6ef5967653fcffe7
+        .quad   0x097c29e8c1ce1ea5
+        .quad   0x5c3cecb943f5a53b
+        .quad   0x9cc9a61d06c08df2
+        .quad   0xcfba639a85895447
+        .quad   0x5a845ae80df09fd5
+        .quad   0x4ce97dbe5deb94ca
+        .quad   0x38d0a4388c709c48
+        .quad   0xc43eced4a169d097
+        .quad   0x0a1249fff7e587c3
+
+        // 2^152 * 1 * G
+
+        .quad   0x12f0071b276d01c9
+        .quad   0xe7b8bac586c48c70
+        .quad   0x5308129b71d6fba9
+        .quad   0x5d88fbf95a3db792
+        .quad   0x0b408d9e7354b610
+        .quad   0x806b32535ba85b6e
+        .quad   0xdbe63a034a58a207
+        .quad   0x173bd9ddc9a1df2c
+        .quad   0x2b500f1efe5872df
+        .quad   0x58d6582ed43918c1
+        .quad   0xe6ed278ec9673ae0
+        .quad   0x06e1cd13b19ea319
+
+        // 2^152 * 2 * G
+
+        .quad   0x40d0ad516f166f23
+        .quad   0x118e32931fab6abe
+        .quad   0x3fe35e14a04d088e
+        .quad   0x3080603526e16266
+        .quad   0x472baf629e5b0353
+        .quad   0x3baa0b90278d0447
+        .quad   0x0c785f469643bf27
+        .quad   0x7f3a6a1a8d837b13
+        .quad   0xf7e644395d3d800b
+        .quad   0x95a8d555c901edf6
+        .quad   0x68cd7830592c6339
+        .quad   0x30d0fded2e51307e
+
+        // 2^152 * 3 * G
+
+        .quad   0xe0594d1af21233b3
+        .quad   0x1bdbe78ef0cc4d9c
+        .quad   0x6965187f8f499a77
+        .quad   0x0a9214202c099868
+        .quad   0x9cb4971e68b84750
+        .quad   0xa09572296664bbcf
+        .quad   0x5c8de72672fa412b
+        .quad   0x4615084351c589d9
+        .quad   0xbc9019c0aeb9a02e
+        .quad   0x55c7110d16034cae
+        .quad   0x0e6df501659932ec
+        .quad   0x3bca0d2895ca5dfe
+
+        // 2^152 * 4 * G
+
+        .quad   0x40f031bc3c5d62a4
+        .quad   0x19fc8b3ecff07a60
+        .quad   0x98183da2130fb545
+        .quad   0x5631deddae8f13cd
+        .quad   0x9c688eb69ecc01bf
+        .quad   0xf0bc83ada644896f
+        .quad   0xca2d955f5f7a9fe2
+        .quad   0x4ea8b4038df28241
+        .quad   0x2aed460af1cad202
+        .quad   0x46305305a48cee83
+        .quad   0x9121774549f11a5f
+        .quad   0x24ce0930542ca463
+
+        // 2^152 * 5 * G
+
+        .quad   0x1fe890f5fd06c106
+        .quad   0xb5c468355d8810f2
+        .quad   0x827808fe6e8caf3e
+        .quad   0x41d4e3c28a06d74b
+        .quad   0x3fcfa155fdf30b85
+        .quad   0xd2f7168e36372ea4
+        .quad   0xb2e064de6492f844
+        .quad   0x549928a7324f4280
+        .quad   0xf26e32a763ee1a2e
+        .quad   0xae91e4b7d25ffdea
+        .quad   0xbc3bd33bd17f4d69
+        .quad   0x491b66dec0dcff6a
+
+        // 2^152 * 6 * G
+
+        .quad   0x98f5b13dc7ea32a7
+        .quad   0xe3d5f8cc7e16db98
+        .quad   0xac0abf52cbf8d947
+        .quad   0x08f338d0c85ee4ac
+        .quad   0x75f04a8ed0da64a1
+        .quad   0xed222caf67e2284b
+        .quad   0x8234a3791f7b7ba4
+        .quad   0x4cf6b8b0b7018b67
+        .quad   0xc383a821991a73bd
+        .quad   0xab27bc01df320c7a
+        .quad   0xc13d331b84777063
+        .quad   0x530d4a82eb078a99
+
+        // 2^152 * 7 * G
+
+        .quad   0x004c3630e1f94825
+        .quad   0x7e2d78268cab535a
+        .quad   0xc7482323cc84ff8b
+        .quad   0x65ea753f101770b9
+        .quad   0x6d6973456c9abf9e
+        .quad   0x257fb2fc4900a880
+        .quad   0x2bacf412c8cfb850
+        .quad   0x0db3e7e00cbfbd5b
+        .quad   0x3d66fc3ee2096363
+        .quad   0x81d62c7f61b5cb6b
+        .quad   0x0fbe044213443b1a
+        .quad   0x02a4ec1921e1a1db
+
+        // 2^152 * 8 * G
+
+        .quad   0x5ce6259a3b24b8a2
+        .quad   0xb8577acc45afa0b8
+        .quad   0xcccbe6e88ba07037
+        .quad   0x3d143c51127809bf
+        .quad   0xf5c86162f1cf795f
+        .quad   0x118c861926ee57f2
+        .quad   0x172124851c063578
+        .quad   0x36d12b5dec067fcf
+        .quad   0x126d279179154557
+        .quad   0xd5e48f5cfc783a0a
+        .quad   0x36bdb6e8df179bac
+        .quad   0x2ef517885ba82859
+
+        // 2^156 * 1 * G
+
+        .quad   0x88bd438cd11e0d4a
+        .quad   0x30cb610d43ccf308
+        .quad   0xe09a0e3791937bcc
+        .quad   0x4559135b25b1720c
+        .quad   0x1ea436837c6da1e9
+        .quad   0xf9c189af1fb9bdbe
+        .quad   0x303001fcce5dd155
+        .quad   0x28a7c99ebc57be52
+        .quad   0xb8fd9399e8d19e9d
+        .quad   0x908191cb962423ff
+        .quad   0xb2b948d747c742a3
+        .quad   0x37f33226d7fb44c4
+
+        // 2^156 * 2 * G
+
+        .quad   0x0dae8767b55f6e08
+        .quad   0x4a43b3b35b203a02
+        .quad   0xe3725a6e80af8c79
+        .quad   0x0f7a7fd1705fa7a3
+        .quad   0x33912553c821b11d
+        .quad   0x66ed42c241e301df
+        .quad   0x066fcc11104222fd
+        .quad   0x307a3b41c192168f
+        .quad   0x8eeb5d076eb55ce0
+        .quad   0x2fc536bfaa0d925a
+        .quad   0xbe81830fdcb6c6e8
+        .quad   0x556c7045827baf52
+
+        // 2^156 * 3 * G
+
+        .quad   0x8e2b517302e9d8b7
+        .quad   0xe3e52269248714e8
+        .quad   0xbd4fbd774ca960b5
+        .quad   0x6f4b4199c5ecada9
+        .quad   0xb94b90022bf44406
+        .quad   0xabd4237eff90b534
+        .quad   0x7600a960faf86d3a
+        .quad   0x2f45abdac2322ee3
+        .quad   0x61af4912c8ef8a6a
+        .quad   0xe58fa4fe43fb6e5e
+        .quad   0xb5afcc5d6fd427cf
+        .quad   0x6a5393281e1e11eb
+
+        // 2^156 * 4 * G
+
+        .quad   0xf3da5139a5d1ee89
+        .quad   0x8145457cff936988
+        .quad   0x3f622fed00e188c4
+        .quad   0x0f513815db8b5a3d
+        .quad   0x0fff04fe149443cf
+        .quad   0x53cac6d9865cddd7
+        .quad   0x31385b03531ed1b7
+        .quad   0x5846a27cacd1039d
+        .quad   0x4ff5cdac1eb08717
+        .quad   0x67e8b29590f2e9bc
+        .quad   0x44093b5e237afa99
+        .quad   0x0d414bed8708b8b2
+
+        // 2^156 * 5 * G
+
+        .quad   0xcfb68265fd0e75f6
+        .quad   0xe45b3e28bb90e707
+        .quad   0x7242a8de9ff92c7a
+        .quad   0x685b3201933202dd
+        .quad   0x81886a92294ac9e8
+        .quad   0x23162b45d55547be
+        .quad   0x94cfbc4403715983
+        .quad   0x50eb8fdb134bc401
+        .quad   0xc0b73ec6d6b330cd
+        .quad   0x84e44807132faff1
+        .quad   0x732b7352c4a5dee1
+        .quad   0x5d7c7cf1aa7cd2d2
+
+        // 2^156 * 6 * G
+
+        .quad   0xaf3b46bf7a4aafa2
+        .quad   0xb78705ec4d40d411
+        .quad   0x114f0c6aca7c15e3
+        .quad   0x3f364faaa9489d4d
+        .quad   0x33d1013e9b73a562
+        .quad   0x925cef5748ec26e1
+        .quad   0xa7fce614dd468058
+        .quad   0x78b0fad41e9aa438
+        .quad   0xbf56a431ed05b488
+        .quad   0xa533e66c9c495c7e
+        .quad   0xe8652baf87f3651a
+        .quad   0x0241800059d66c33
+
+        // 2^156 * 7 * G
+
+        .quad   0xceb077fea37a5be4
+        .quad   0xdb642f02e5a5eeb7
+        .quad   0xc2e6d0c5471270b8
+        .quad   0x4771b65538e4529c
+        .quad   0x28350c7dcf38ea01
+        .quad   0x7c6cdbc0b2917ab6
+        .quad   0xace7cfbe857082f7
+        .quad   0x4d2845aba2d9a1e0
+        .quad   0xbb537fe0447070de
+        .quad   0xcba744436dd557df
+        .quad   0xd3b5a3473600dbcb
+        .quad   0x4aeabbe6f9ffd7f8
+
+        // 2^156 * 8 * G
+
+        .quad   0x4630119e40d8f78c
+        .quad   0xa01a9bc53c710e11
+        .quad   0x486d2b258910dd79
+        .quad   0x1e6c47b3db0324e5
+        .quad   0x6a2134bcc4a9c8f2
+        .quad   0xfbf8fd1c8ace2e37
+        .quad   0x000ae3049911a0ba
+        .quad   0x046e3a616bc89b9e
+        .quad   0x14e65442f03906be
+        .quad   0x4a019d54e362be2a
+        .quad   0x68ccdfec8dc230c7
+        .quad   0x7cfb7e3faf6b861c
+
+        // 2^160 * 1 * G
+
+        .quad   0x4637974e8c58aedc
+        .quad   0xb9ef22fbabf041a4
+        .quad   0xe185d956e980718a
+        .quad   0x2f1b78fab143a8a6
+        .quad   0x96eebffb305b2f51
+        .quad   0xd3f938ad889596b8
+        .quad   0xf0f52dc746d5dd25
+        .quad   0x57968290bb3a0095
+        .quad   0xf71ab8430a20e101
+        .quad   0xf393658d24f0ec47
+        .quad   0xcf7509a86ee2eed1
+        .quad   0x7dc43e35dc2aa3e1
+
+        // 2^160 * 2 * G
+
+        .quad   0x85966665887dd9c3
+        .quad   0xc90f9b314bb05355
+        .quad   0xc6e08df8ef2079b1
+        .quad   0x7ef72016758cc12f
+        .quad   0x5a782a5c273e9718
+        .quad   0x3576c6995e4efd94
+        .quad   0x0f2ed8051f237d3e
+        .quad   0x044fb81d82d50a99
+        .quad   0xc1df18c5a907e3d9
+        .quad   0x57b3371dce4c6359
+        .quad   0xca704534b201bb49
+        .quad   0x7f79823f9c30dd2e
+
+        // 2^160 * 3 * G
+
+        .quad   0x8334d239a3b513e8
+        .quad   0xc13670d4b91fa8d8
+        .quad   0x12b54136f590bd33
+        .quad   0x0a4e0373d784d9b4
+        .quad   0x6a9c1ff068f587ba
+        .quad   0x0827894e0050c8de
+        .quad   0x3cbf99557ded5be7
+        .quad   0x64a9b0431c06d6f0
+        .quad   0x2eb3d6a15b7d2919
+        .quad   0xb0b4f6a0d53a8235
+        .quad   0x7156ce4389a45d47
+        .quad   0x071a7d0ace18346c
+
+        // 2^160 * 4 * G
+
+        .quad   0xd3072daac887ba0b
+        .quad   0x01262905bfa562ee
+        .quad   0xcf543002c0ef768b
+        .quad   0x2c3bcc7146ea7e9c
+        .quad   0xcc0c355220e14431
+        .quad   0x0d65950709b15141
+        .quad   0x9af5621b209d5f36
+        .quad   0x7c69bcf7617755d3
+        .quad   0x07f0d7eb04e8295f
+        .quad   0x10db18252f50f37d
+        .quad   0xe951a9a3171798d7
+        .quad   0x6f5a9a7322aca51d
+
+        // 2^160 * 5 * G
+
+        .quad   0x8ba1000c2f41c6c5
+        .quad   0xc49f79c10cfefb9b
+        .quad   0x4efa47703cc51c9f
+        .quad   0x494e21a2e147afca
+        .quad   0xe729d4eba3d944be
+        .quad   0x8d9e09408078af9e
+        .quad   0x4525567a47869c03
+        .quad   0x02ab9680ee8d3b24
+        .quad   0xefa48a85dde50d9a
+        .quad   0x219a224e0fb9a249
+        .quad   0xfa091f1dd91ef6d9
+        .quad   0x6b5d76cbea46bb34
+
+        // 2^160 * 6 * G
+
+        .quad   0x8857556cec0cd994
+        .quad   0x6472dc6f5cd01dba
+        .quad   0xaf0169148f42b477
+        .quad   0x0ae333f685277354
+        .quad   0xe0f941171e782522
+        .quad   0xf1e6ae74036936d3
+        .quad   0x408b3ea2d0fcc746
+        .quad   0x16fb869c03dd313e
+        .quad   0x288e199733b60962
+        .quad   0x24fc72b4d8abe133
+        .quad   0x4811f7ed0991d03e
+        .quad   0x3f81e38b8f70d075
+
+        // 2^160 * 7 * G
+
+        .quad   0x7f910fcc7ed9affe
+        .quad   0x545cb8a12465874b
+        .quad   0xa8397ed24b0c4704
+        .quad   0x50510fc104f50993
+        .quad   0x0adb7f355f17c824
+        .quad   0x74b923c3d74299a4
+        .quad   0xd57c3e8bcbf8eaf7
+        .quad   0x0ad3e2d34cdedc3d
+        .quad   0x6f0c0fc5336e249d
+        .quad   0x745ede19c331cfd9
+        .quad   0xf2d6fd0009eefe1c
+        .quad   0x127c158bf0fa1ebe
+
+        // 2^160 * 8 * G
+
+        .quad   0xf6197c422e9879a2
+        .quad   0xa44addd452ca3647
+        .quad   0x9b413fc14b4eaccb
+        .quad   0x354ef87d07ef4f68
+        .quad   0xdea28fc4ae51b974
+        .quad   0x1d9973d3744dfe96
+        .quad   0x6240680b873848a8
+        .quad   0x4ed82479d167df95
+        .quad   0xfee3b52260c5d975
+        .quad   0x50352efceb41b0b8
+        .quad   0x8808ac30a9f6653c
+        .quad   0x302d92d20539236d
+
+        // 2^164 * 1 * G
+
+        .quad   0x4c59023fcb3efb7c
+        .quad   0x6c2fcb99c63c2a94
+        .quad   0xba4190e2c3c7e084
+        .quad   0x0e545daea51874d9
+        .quad   0x957b8b8b0df53c30
+        .quad   0x2a1c770a8e60f098
+        .quad   0xbbc7a670345796de
+        .quad   0x22a48f9a90c99bc9
+        .quad   0x6b7dc0dc8d3fac58
+        .quad   0x5497cd6ce6e42bfd
+        .quad   0x542f7d1bf400d305
+        .quad   0x4159f47f048d9136
+
+        // 2^164 * 2 * G
+
+        .quad   0x20ad660839e31e32
+        .quad   0xf81e1bd58405be50
+        .quad   0xf8064056f4dabc69
+        .quad   0x14d23dd4ce71b975
+        .quad   0x748515a8bbd24839
+        .quad   0x77128347afb02b55
+        .quad   0x50ba2ac649a2a17f
+        .quad   0x060525513ad730f1
+        .quad   0xf2398e098aa27f82
+        .quad   0x6d7982bb89a1b024
+        .quad   0xfa694084214dd24c
+        .quad   0x71ab966fa32301c3
+
+        // 2^164 * 3 * G
+
+        .quad   0x2dcbd8e34ded02fc
+        .quad   0x1151f3ec596f22aa
+        .quad   0xbca255434e0328da
+        .quad   0x35768fbe92411b22
+        .quad   0xb1088a0702809955
+        .quad   0x43b273ea0b43c391
+        .quad   0xca9b67aefe0686ed
+        .quad   0x605eecbf8335f4ed
+        .quad   0x83200a656c340431
+        .quad   0x9fcd71678ee59c2f
+        .quad   0x75d4613f71300f8a
+        .quad   0x7a912faf60f542f9
+
+        // 2^164 * 4 * G
+
+        .quad   0xb204585e5edc1a43
+        .quad   0x9f0e16ee5897c73c
+        .quad   0x5b82c0ae4e70483c
+        .quad   0x624a170e2bddf9be
+        .quad   0x253f4f8dfa2d5597
+        .quad   0x25e49c405477130c
+        .quad   0x00c052e5996b1102
+        .quad   0x33cb966e33bb6c4a
+        .quad   0x597028047f116909
+        .quad   0x828ac41c1e564467
+        .quad   0x70417dbde6217387
+        .quad   0x721627aefbac4384
+
+        // 2^164 * 5 * G
+
+        .quad   0x97d03bc38736add5
+        .quad   0x2f1422afc532b130
+        .quad   0x3aa68a057101bbc4
+        .quad   0x4c946cf7e74f9fa7
+        .quad   0xfd3097bc410b2f22
+        .quad   0xf1a05da7b5cfa844
+        .quad   0x61289a1def57ca74
+        .quad   0x245ea199bb821902
+        .quad   0xaedca66978d477f8
+        .quad   0x1898ba3c29117fe1
+        .quad   0xcf73f983720cbd58
+        .quad   0x67da12e6b8b56351
+
+        // 2^164 * 6 * G
+
+        .quad   0x7067e187b4bd6e07
+        .quad   0x6e8f0203c7d1fe74
+        .quad   0x93c6aa2f38c85a30
+        .quad   0x76297d1f3d75a78a
+        .quad   0x2b7ef3d38ec8308c
+        .quad   0x828fd7ec71eb94ab
+        .quad   0x807c3b36c5062abd
+        .quad   0x0cb64cb831a94141
+        .quad   0x3030fc33534c6378
+        .quad   0xb9635c5ce541e861
+        .quad   0x15d9a9bed9b2c728
+        .quad   0x49233ea3f3775dcb
+
+        // 2^164 * 7 * G
+
+        .quad   0x629398fa8dbffc3a
+        .quad   0xe12fe52dd54db455
+        .quad   0xf3be11dfdaf25295
+        .quad   0x628b140dce5e7b51
+        .quad   0x7b3985fe1c9f249b
+        .quad   0x4fd6b2d5a1233293
+        .quad   0xceb345941adf4d62
+        .quad   0x6987ff6f542de50c
+        .quad   0x47e241428f83753c
+        .quad   0x6317bebc866af997
+        .quad   0xdabb5b433d1a9829
+        .quad   0x074d8d245287fb2d
+
+        // 2^164 * 8 * G
+
+        .quad   0x8337d9cd440bfc31
+        .quad   0x729d2ca1af318fd7
+        .quad   0xa040a4a4772c2070
+        .quad   0x46002ef03a7349be
+        .quad   0x481875c6c0e31488
+        .quad   0x219429b2e22034b4
+        .quad   0x7223c98a31283b65
+        .quad   0x3420d60b342277f9
+        .quad   0xfaa23adeaffe65f7
+        .quad   0x78261ed45be0764c
+        .quad   0x441c0a1e2f164403
+        .quad   0x5aea8e567a87d395
+
+        // 2^168 * 1 * G
+
+        .quad   0x7813c1a2bca4283d
+        .quad   0xed62f091a1863dd9
+        .quad   0xaec7bcb8c268fa86
+        .quad   0x10e5d3b76f1cae4c
+        .quad   0x2dbc6fb6e4e0f177
+        .quad   0x04e1bf29a4bd6a93
+        .quad   0x5e1966d4787af6e8
+        .quad   0x0edc5f5eb426d060
+        .quad   0x5453bfd653da8e67
+        .quad   0xe9dc1eec24a9f641
+        .quad   0xbf87263b03578a23
+        .quad   0x45b46c51361cba72
+
+        // 2^168 * 2 * G
+
+        .quad   0xa9402abf314f7fa1
+        .quad   0xe257f1dc8e8cf450
+        .quad   0x1dbbd54b23a8be84
+        .quad   0x2177bfa36dcb713b
+        .quad   0xce9d4ddd8a7fe3e4
+        .quad   0xab13645676620e30
+        .quad   0x4b594f7bb30e9958
+        .quad   0x5c1c0aef321229df
+        .quad   0x37081bbcfa79db8f
+        .quad   0x6048811ec25f59b3
+        .quad   0x087a76659c832487
+        .quad   0x4ae619387d8ab5bb
+
+        // 2^168 * 3 * G
+
+        .quad   0x8ddbf6aa5344a32e
+        .quad   0x7d88eab4b41b4078
+        .quad   0x5eb0eb974a130d60
+        .quad   0x1a00d91b17bf3e03
+        .quad   0x61117e44985bfb83
+        .quad   0xfce0462a71963136
+        .quad   0x83ac3448d425904b
+        .quad   0x75685abe5ba43d64
+        .quad   0x6e960933eb61f2b2
+        .quad   0x543d0fa8c9ff4952
+        .quad   0xdf7275107af66569
+        .quad   0x135529b623b0e6aa
+
+        // 2^168 * 4 * G
+
+        .quad   0x18f0dbd7add1d518
+        .quad   0x979f7888cfc11f11
+        .quad   0x8732e1f07114759b
+        .quad   0x79b5b81a65ca3a01
+        .quad   0xf5c716bce22e83fe
+        .quad   0xb42beb19e80985c1
+        .quad   0xec9da63714254aae
+        .quad   0x5972ea051590a613
+        .quad   0x0fd4ac20dc8f7811
+        .quad   0x9a9ad294ac4d4fa8
+        .quad   0xc01b2d64b3360434
+        .quad   0x4f7e9c95905f3bdb
+
+        // 2^168 * 5 * G
+
+        .quad   0x62674bbc5781302e
+        .quad   0xd8520f3989addc0f
+        .quad   0x8c2999ae53fbd9c6
+        .quad   0x31993ad92e638e4c
+        .quad   0x71c8443d355299fe
+        .quad   0x8bcd3b1cdbebead7
+        .quad   0x8092499ef1a49466
+        .quad   0x1942eec4a144adc8
+        .quad   0x7dac5319ae234992
+        .quad   0x2c1b3d910cea3e92
+        .quad   0x553ce494253c1122
+        .quad   0x2a0a65314ef9ca75
+
+        // 2^168 * 6 * G
+
+        .quad   0x2db7937ff7f927c2
+        .quad   0xdb741f0617d0a635
+        .quad   0x5982f3a21155af76
+        .quad   0x4cf6e218647c2ded
+        .quad   0xcf361acd3c1c793a
+        .quad   0x2f9ebcac5a35bc3b
+        .quad   0x60e860e9a8cda6ab
+        .quad   0x055dc39b6dea1a13
+        .quad   0xb119227cc28d5bb6
+        .quad   0x07e24ebc774dffab
+        .quad   0xa83c78cee4a32c89
+        .quad   0x121a307710aa24b6
+
+        // 2^168 * 7 * G
+
+        .quad   0xe4db5d5e9f034a97
+        .quad   0xe153fc093034bc2d
+        .quad   0x460546919551d3b1
+        .quad   0x333fc76c7a40e52d
+        .quad   0xd659713ec77483c9
+        .quad   0x88bfe077b82b96af
+        .quad   0x289e28231097bcd3
+        .quad   0x527bb94a6ced3a9b
+        .quad   0x563d992a995b482e
+        .quad   0x3405d07c6e383801
+        .quad   0x485035de2f64d8e5
+        .quad   0x6b89069b20a7a9f7
+
+        // 2^168 * 8 * G
+
+        .quad   0x812aa0416270220d
+        .quad   0x995a89faf9245b4e
+        .quad   0xffadc4ce5072ef05
+        .quad   0x23bc2103aa73eb73
+        .quad   0x4082fa8cb5c7db77
+        .quad   0x068686f8c734c155
+        .quad   0x29e6c8d9f6e7a57e
+        .quad   0x0473d308a7639bcf
+        .quad   0xcaee792603589e05
+        .quad   0x2b4b421246dcc492
+        .quad   0x02a1ef74e601a94f
+        .quad   0x102f73bfde04341a
+
+        // 2^172 * 1 * G
+
+        .quad   0xb5a2d50c7ec20d3e
+        .quad   0xc64bdd6ea0c97263
+        .quad   0x56e89052c1ff734d
+        .quad   0x4929c6f72b2ffaba
+        .quad   0x358ecba293a36247
+        .quad   0xaf8f9862b268fd65
+        .quad   0x412f7e9968a01c89
+        .quad   0x5786f312cd754524
+        .quad   0x337788ffca14032c
+        .quad   0xf3921028447f1ee3
+        .quad   0x8b14071f231bccad
+        .quad   0x4c817b4bf2344783
+
+        // 2^172 * 2 * G
+
+        .quad   0x0ff853852871b96e
+        .quad   0xe13e9fab60c3f1bb
+        .quad   0xeefd595325344402
+        .quad   0x0a37c37075b7744b
+        .quad   0x413ba057a40b4484
+        .quad   0xba4c2e1a4f5f6a43
+        .quad   0x614ba0a5aee1d61c
+        .quad   0x78a1531a8b05dc53
+        .quad   0x6cbdf1703ad0562b
+        .quad   0x8ecf4830c92521a3
+        .quad   0xdaebd303fd8424e7
+        .quad   0x72ad82a42e5ec56f
+
+        // 2^172 * 3 * G
+
+        .quad   0x3f9e8e35bafb65f6
+        .quad   0x39d69ec8f27293a1
+        .quad   0x6cb8cd958cf6a3d0
+        .quad   0x1734778173adae6d
+        .quad   0xc368939167024bc3
+        .quad   0x8e69d16d49502fda
+        .quad   0xfcf2ec3ce45f4b29
+        .quad   0x065f669ea3b4cbc4
+        .quad   0x8a00aec75532db4d
+        .quad   0xb869a4e443e31bb1
+        .quad   0x4a0f8552d3a7f515
+        .quad   0x19adeb7c303d7c08
+
+        // 2^172 * 4 * G
+
+        .quad   0xc720cb6153ead9a3
+        .quad   0x55b2c97f512b636e
+        .quad   0xb1e35b5fd40290b1
+        .quad   0x2fd9ccf13b530ee2
+        .quad   0x9d05ba7d43c31794
+        .quad   0x2470c8ff93322526
+        .quad   0x8323dec816197438
+        .quad   0x2852709881569b53
+        .quad   0x07bd475b47f796b8
+        .quad   0xd2c7b013542c8f54
+        .quad   0x2dbd23f43b24f87e
+        .quad   0x6551afd77b0901d6
+
+        // 2^172 * 5 * G
+
+        .quad   0x4546baaf54aac27f
+        .quad   0xf6f66fecb2a45a28
+        .quad   0x582d1b5b562bcfe8
+        .quad   0x44b123f3920f785f
+        .quad   0x68a24ce3a1d5c9ac
+        .quad   0xbb77a33d10ff6461
+        .quad   0x0f86ce4425d3166e
+        .quad   0x56507c0950b9623b
+        .quad   0x1206f0b7d1713e63
+        .quad   0x353fe3d915bafc74
+        .quad   0x194ceb970ad9d94d
+        .quad   0x62fadd7cf9d03ad3
+
+        // 2^172 * 6 * G
+
+        .quad   0xc6b5967b5598a074
+        .quad   0x5efe91ce8e493e25
+        .quad   0xd4b72c4549280888
+        .quad   0x20ef1149a26740c2
+        .quad   0x3cd7bc61e7ce4594
+        .quad   0xcd6b35a9b7dd267e
+        .quad   0xa080abc84366ef27
+        .quad   0x6ec7c46f59c79711
+        .quad   0x2f07ad636f09a8a2
+        .quad   0x8697e6ce24205e7d
+        .quad   0xc0aefc05ee35a139
+        .quad   0x15e80958b5f9d897
+
+        // 2^172 * 7 * G
+
+        .quad   0x25a5ef7d0c3e235b
+        .quad   0x6c39c17fbe134ee7
+        .quad   0xc774e1342dc5c327
+        .quad   0x021354b892021f39
+        .quad   0x4dd1ed355bb061c4
+        .quad   0x42dc0cef941c0700
+        .quad   0x61305dc1fd86340e
+        .quad   0x56b2cc930e55a443
+        .quad   0x1df79da6a6bfc5a2
+        .quad   0x02f3a2749fde4369
+        .quad   0xb323d9f2cda390a7
+        .quad   0x7be0847b8774d363
+
+        // 2^172 * 8 * G
+
+        .quad   0x8c99cc5a8b3f55c3
+        .quad   0x0611d7253fded2a0
+        .quad   0xed2995ff36b70a36
+        .quad   0x1f699a54d78a2619
+        .quad   0x1466f5af5307fa11
+        .quad   0x817fcc7ded6c0af2
+        .quad   0x0a6de44ec3a4a3fb
+        .quad   0x74071475bc927d0b
+        .quad   0xe77292f373e7ea8a
+        .quad   0x296537d2cb045a31
+        .quad   0x1bd0653ed3274fde
+        .quad   0x2f9a2c4476bd2966
+
+        // 2^176 * 1 * G
+
+        .quad   0xeb18b9ab7f5745c6
+        .quad   0x023a8aee5787c690
+        .quad   0xb72712da2df7afa9
+        .quad   0x36597d25ea5c013d
+        .quad   0xa2b4dae0b5511c9a
+        .quad   0x7ac860292bffff06
+        .quad   0x981f375df5504234
+        .quad   0x3f6bd725da4ea12d
+        .quad   0x734d8d7b106058ac
+        .quad   0xd940579e6fc6905f
+        .quad   0x6466f8f99202932d
+        .quad   0x7b7ecc19da60d6d0
+
+        // 2^176 * 2 * G
+
+        .quad   0x78c2373c695c690d
+        .quad   0xdd252e660642906e
+        .quad   0x951d44444ae12bd2
+        .quad   0x4235ad7601743956
+        .quad   0x6dae4a51a77cfa9b
+        .quad   0x82263654e7a38650
+        .quad   0x09bbffcd8f2d82db
+        .quad   0x03bedc661bf5caba
+        .quad   0x6258cb0d078975f5
+        .quad   0x492942549189f298
+        .quad   0xa0cab423e2e36ee4
+        .quad   0x0e7ce2b0cdf066a1
+
+        // 2^176 * 3 * G
+
+        .quad   0xc494643ac48c85a3
+        .quad   0xfd361df43c6139ad
+        .quad   0x09db17dd3ae94d48
+        .quad   0x666e0a5d8fb4674a
+        .quad   0xfea6fedfd94b70f9
+        .quad   0xf130c051c1fcba2d
+        .quad   0x4882d47e7f2fab89
+        .quad   0x615256138aeceeb5
+        .quad   0x2abbf64e4870cb0d
+        .quad   0xcd65bcf0aa458b6b
+        .quad   0x9abe4eba75e8985d
+        .quad   0x7f0bc810d514dee4
+
+        // 2^176 * 4 * G
+
+        .quad   0xb9006ba426f4136f
+        .quad   0x8d67369e57e03035
+        .quad   0xcbc8dfd94f463c28
+        .quad   0x0d1f8dbcf8eedbf5
+        .quad   0x83ac9dad737213a0
+        .quad   0x9ff6f8ba2ef72e98
+        .quad   0x311e2edd43ec6957
+        .quad   0x1d3a907ddec5ab75
+        .quad   0xba1693313ed081dc
+        .quad   0x29329fad851b3480
+        .quad   0x0128013c030321cb
+        .quad   0x00011b44a31bfde3
+
+        // 2^176 * 5 * G
+
+        .quad   0x3fdfa06c3fc66c0c
+        .quad   0x5d40e38e4dd60dd2
+        .quad   0x7ae38b38268e4d71
+        .quad   0x3ac48d916e8357e1
+        .quad   0x16561f696a0aa75c
+        .quad   0xc1bf725c5852bd6a
+        .quad   0x11a8dd7f9a7966ad
+        .quad   0x63d988a2d2851026
+        .quad   0x00120753afbd232e
+        .quad   0xe92bceb8fdd8f683
+        .quad   0xf81669b384e72b91
+        .quad   0x33fad52b2368a066
+
+        // 2^176 * 6 * G
+
+        .quad   0x540649c6c5e41e16
+        .quad   0x0af86430333f7735
+        .quad   0xb2acfcd2f305e746
+        .quad   0x16c0f429a256dca7
+        .quad   0x8d2cc8d0c422cfe8
+        .quad   0x072b4f7b05a13acb
+        .quad   0xa3feb6e6ecf6a56f
+        .quad   0x3cc355ccb90a71e2
+        .quad   0xe9b69443903e9131
+        .quad   0xb8a494cb7a5637ce
+        .quad   0xc87cd1a4baba9244
+        .quad   0x631eaf426bae7568
+
+        // 2^176 * 7 * G
+
+        .quad   0xb3e90410da66fe9f
+        .quad   0x85dd4b526c16e5a6
+        .quad   0xbc3d97611ef9bf83
+        .quad   0x5599648b1ea919b5
+        .quad   0x47d975b9a3700de8
+        .quad   0x7280c5fbe2f80552
+        .quad   0x53658f2732e45de1
+        .quad   0x431f2c7f665f80b5
+        .quad   0xd6026344858f7b19
+        .quad   0x14ab352fa1ea514a
+        .quad   0x8900441a2090a9d7
+        .quad   0x7b04715f91253b26
+
+        // 2^176 * 8 * G
+
+        .quad   0x83edbd28acf6ae43
+        .quad   0x86357c8b7d5c7ab4
+        .quad   0xc0404769b7eb2c44
+        .quad   0x59b37bf5c2f6583f
+        .quad   0xb376c280c4e6bac6
+        .quad   0x970ed3dd6d1d9b0b
+        .quad   0xb09a9558450bf944
+        .quad   0x48d0acfa57cde223
+        .quad   0xb60f26e47dabe671
+        .quad   0xf1d1a197622f3a37
+        .quad   0x4208ce7ee9960394
+        .quad   0x16234191336d3bdb
+
+        // 2^180 * 1 * G
+
+        .quad   0xf19aeac733a63aef
+        .quad   0x2c7fba5d4442454e
+        .quad   0x5da87aa04795e441
+        .quad   0x413051e1a4e0b0f5
+        .quad   0x852dd1fd3d578bbe
+        .quad   0x2b65ce72c3286108
+        .quad   0x658c07f4eace2273
+        .quad   0x0933f804ec38ab40
+        .quad   0xa7ab69798d496476
+        .quad   0x8121aadefcb5abc8
+        .quad   0xa5dc12ef7b539472
+        .quad   0x07fd47065e45351a
+
+        // 2^180 * 2 * G
+
+        .quad   0xc8583c3d258d2bcd
+        .quad   0x17029a4daf60b73f
+        .quad   0xfa0fc9d6416a3781
+        .quad   0x1c1e5fba38b3fb23
+        .quad   0x304211559ae8e7c3
+        .quad   0xf281b229944882a5
+        .quad   0x8a13ac2e378250e4
+        .quad   0x014afa0954ba48f4
+        .quad   0xcb3197001bb3666c
+        .quad   0x330060524bffecb9
+        .quad   0x293711991a88233c
+        .quad   0x291884363d4ed364
+
+        // 2^180 * 3 * G
+
+        .quad   0x033c6805dc4babfa
+        .quad   0x2c15bf5e5596ecc1
+        .quad   0x1bc70624b59b1d3b
+        .quad   0x3ede9850a19f0ec5
+        .quad   0xfb9d37c3bc1ab6eb
+        .quad   0x02be14534d57a240
+        .quad   0xf4d73415f8a5e1f6
+        .quad   0x5964f4300ccc8188
+        .quad   0xe44a23152d096800
+        .quad   0x5c08c55970866996
+        .quad   0xdf2db60a46affb6e
+        .quad   0x579155c1f856fd89
+
+        // 2^180 * 4 * G
+
+        .quad   0x96324edd12e0c9ef
+        .quad   0x468b878df2420297
+        .quad   0x199a3776a4f573be
+        .quad   0x1e7fbcf18e91e92a
+        .quad   0xb5f16b630817e7a6
+        .quad   0x808c69233c351026
+        .quad   0x324a983b54cef201
+        .quad   0x53c092084a485345
+        .quad   0xd2d41481f1cbafbf
+        .quad   0x231d2db6716174e5
+        .quad   0x0b7d7656e2a55c98
+        .quad   0x3e955cd82aa495f6
+
+        // 2^180 * 5 * G
+
+        .quad   0xe48f535e3ed15433
+        .quad   0xd075692a0d7270a3
+        .quad   0x40fbd21daade6387
+        .quad   0x14264887cf4495f5
+        .quad   0xab39f3ef61bb3a3f
+        .quad   0x8eb400652eb9193e
+        .quad   0xb5de6ecc38c11f74
+        .quad   0x654d7e9626f3c49f
+        .quad   0xe564cfdd5c7d2ceb
+        .quad   0x82eeafded737ccb9
+        .quad   0x6107db62d1f9b0ab
+        .quad   0x0b6baac3b4358dbb
+
+        // 2^180 * 6 * G
+
+        .quad   0x7ae62bcb8622fe98
+        .quad   0x47762256ceb891af
+        .quad   0x1a5a92bcf2e406b4
+        .quad   0x7d29401784e41501
+        .quad   0x204abad63700a93b
+        .quad   0xbe0023d3da779373
+        .quad   0xd85f0346633ab709
+        .quad   0x00496dc490820412
+        .quad   0x1c74b88dc27e6360
+        .quad   0x074854268d14850c
+        .quad   0xa145fb7b3e0dcb30
+        .quad   0x10843f1b43803b23
+
+        // 2^180 * 7 * G
+
+        .quad   0xc5f90455376276dd
+        .quad   0xce59158dd7645cd9
+        .quad   0x92f65d511d366b39
+        .quad   0x11574b6e526996c4
+        .quad   0xd56f672de324689b
+        .quad   0xd1da8aedb394a981
+        .quad   0xdd7b58fe9168cfed
+        .quad   0x7ce246cd4d56c1e8
+        .quad   0xb8f4308e7f80be53
+        .quad   0x5f3cb8cb34a9d397
+        .quad   0x18a961bd33cc2b2c
+        .quad   0x710045fb3a9af671
+
+        // 2^180 * 8 * G
+
+        .quad   0x73f93d36101b95eb
+        .quad   0xfaef33794f6f4486
+        .quad   0x5651735f8f15e562
+        .quad   0x7fa3f19058b40da1
+        .quad   0xa03fc862059d699e
+        .quad   0x2370cfa19a619e69
+        .quad   0xc4fe3b122f823deb
+        .quad   0x1d1b056fa7f0844e
+        .quad   0x1bc64631e56bf61f
+        .quad   0xd379ab106e5382a3
+        .quad   0x4d58c57e0540168d
+        .quad   0x566256628442d8e4
+
+        // 2^184 * 1 * G
+
+        .quad   0xb9e499def6267ff6
+        .quad   0x7772ca7b742c0843
+        .quad   0x23a0153fe9a4f2b1
+        .quad   0x2cdfdfecd5d05006
+        .quad   0xdd499cd61ff38640
+        .quad   0x29cd9bc3063625a0
+        .quad   0x51e2d8023dd73dc3
+        .quad   0x4a25707a203b9231
+        .quad   0x2ab7668a53f6ed6a
+        .quad   0x304242581dd170a1
+        .quad   0x4000144c3ae20161
+        .quad   0x5721896d248e49fc
+
+        // 2^184 * 2 * G
+
+        .quad   0x0b6e5517fd181bae
+        .quad   0x9022629f2bb963b4
+        .quad   0x5509bce932064625
+        .quad   0x578edd74f63c13da
+        .quad   0x285d5091a1d0da4e
+        .quad   0x4baa6fa7b5fe3e08
+        .quad   0x63e5177ce19393b3
+        .quad   0x03c935afc4b030fd
+        .quad   0x997276c6492b0c3d
+        .quad   0x47ccc2c4dfe205fc
+        .quad   0xdcd29b84dd623a3c
+        .quad   0x3ec2ab590288c7a2
+
+        // 2^184 * 3 * G
+
+        .quad   0xa1a0d27be4d87bb9
+        .quad   0xa98b4deb61391aed
+        .quad   0x99a0ddd073cb9b83
+        .quad   0x2dd5c25a200fcace
+        .quad   0xa7213a09ae32d1cb
+        .quad   0x0f2b87df40f5c2d5
+        .quad   0x0baea4c6e81eab29
+        .quad   0x0e1bf66c6adbac5e
+        .quad   0xe2abd5e9792c887e
+        .quad   0x1a020018cb926d5d
+        .quad   0xbfba69cdbaae5f1e
+        .quad   0x730548b35ae88f5f
+
+        // 2^184 * 4 * G
+
+        .quad   0xc43551a3cba8b8ee
+        .quad   0x65a26f1db2115f16
+        .quad   0x760f4f52ab8c3850
+        .quad   0x3043443b411db8ca
+        .quad   0x805b094ba1d6e334
+        .quad   0xbf3ef17709353f19
+        .quad   0x423f06cb0622702b
+        .quad   0x585a2277d87845dd
+        .quad   0xa18a5f8233d48962
+        .quad   0x6698c4b5ec78257f
+        .quad   0xa78e6fa5373e41ff
+        .quad   0x7656278950ef981f
+
+        // 2^184 * 5 * G
+
+        .quad   0x38c3cf59d51fc8c0
+        .quad   0x9bedd2fd0506b6f2
+        .quad   0x26bf109fab570e8f
+        .quad   0x3f4160a8c1b846a6
+        .quad   0xe17073a3ea86cf9d
+        .quad   0x3a8cfbb707155fdc
+        .quad   0x4853e7fc31838a8e
+        .quad   0x28bbf484b613f616
+        .quad   0xf2612f5c6f136c7c
+        .quad   0xafead107f6dd11be
+        .quad   0x527e9ad213de6f33
+        .quad   0x1e79cb358188f75d
+
+        // 2^184 * 6 * G
+
+        .quad   0x013436c3eef7e3f1
+        .quad   0x828b6a7ffe9e10f8
+        .quad   0x7ff908e5bcf9defc
+        .quad   0x65d7951b3a3b3831
+        .quad   0x77e953d8f5e08181
+        .quad   0x84a50c44299dded9
+        .quad   0xdc6c2d0c864525e5
+        .quad   0x478ab52d39d1f2f4
+        .quad   0x66a6a4d39252d159
+        .quad   0xe5dde1bc871ac807
+        .quad   0xb82c6b40a6c1c96f
+        .quad   0x16d87a411a212214
+
+        // 2^184 * 7 * G
+
+        .quad   0xb3bd7e5a42066215
+        .quad   0x879be3cd0c5a24c1
+        .quad   0x57c05db1d6f994b7
+        .quad   0x28f87c8165f38ca6
+        .quad   0xfba4d5e2d54e0583
+        .quad   0xe21fafd72ebd99fa
+        .quad   0x497ac2736ee9778f
+        .quad   0x1f990b577a5a6dde
+        .quad   0xa3344ead1be8f7d6
+        .quad   0x7d1e50ebacea798f
+        .quad   0x77c6569e520de052
+        .quad   0x45882fe1534d6d3e
+
+        // 2^184 * 8 * G
+
+        .quad   0x6669345d757983d6
+        .quad   0x62b6ed1117aa11a6
+        .quad   0x7ddd1857985e128f
+        .quad   0x688fe5b8f626f6dd
+        .quad   0xd8ac9929943c6fe4
+        .quad   0xb5f9f161a38392a2
+        .quad   0x2699db13bec89af3
+        .quad   0x7dcf843ce405f074
+        .quad   0x6c90d6484a4732c0
+        .quad   0xd52143fdca563299
+        .quad   0xb3be28c3915dc6e1
+        .quad   0x6739687e7327191b
+
+        // 2^188 * 1 * G
+
+        .quad   0x9f65c5ea200814cf
+        .quad   0x840536e169a31740
+        .quad   0x8b0ed13925c8b4ad
+        .quad   0x0080dbafe936361d
+        .quad   0x8ce5aad0c9cb971f
+        .quad   0x1156aaa99fd54a29
+        .quad   0x41f7247015af9b78
+        .quad   0x1fe8cca8420f49aa
+        .quad   0x72a1848f3c0cc82a
+        .quad   0x38c560c2877c9e54
+        .quad   0x5004e228ce554140
+        .quad   0x042418a103429d71
+
+        // 2^188 * 2 * G
+
+        .quad   0x899dea51abf3ff5f
+        .quad   0x9b93a8672fc2d8ba
+        .quad   0x2c38cb97be6ebd5c
+        .quad   0x114d578497263b5d
+        .quad   0x58e84c6f20816247
+        .quad   0x8db2b2b6e36fd793
+        .quad   0x977182561d484d85
+        .quad   0x0822024f8632abd7
+        .quad   0xb301bb7c6b1beca3
+        .quad   0x55393f6dc6eb1375
+        .quad   0x910d281097b6e4eb
+        .quad   0x1ad4548d9d479ea3
+
+        // 2^188 * 3 * G
+
+        .quad   0xcd5a7da0389a48fd
+        .quad   0xb38fa4aa9a78371e
+        .quad   0xc6d9761b2cdb8e6c
+        .quad   0x35cf51dbc97e1443
+        .quad   0xa06fe66d0fe9fed3
+        .quad   0xa8733a401c587909
+        .quad   0x30d14d800df98953
+        .quad   0x41ce5876c7b30258
+        .quad   0x59ac3bc5d670c022
+        .quad   0xeae67c109b119406
+        .quad   0x9798bdf0b3782fda
+        .quad   0x651e3201fd074092
+
+        // 2^188 * 4 * G
+
+        .quad   0xd63d8483ef30c5cf
+        .quad   0x4cd4b4962361cc0c
+        .quad   0xee90e500a48426ac
+        .quad   0x0af51d7d18c14eeb
+        .quad   0xa57ba4a01efcae9e
+        .quad   0x769f4beedc308a94
+        .quad   0xd1f10eeb3603cb2e
+        .quad   0x4099ce5e7e441278
+        .quad   0x1ac98e4f8a5121e9
+        .quad   0x7dae9544dbfa2fe0
+        .quad   0x8320aa0dd6430df9
+        .quad   0x667282652c4a2fb5
+
+        // 2^188 * 5 * G
+
+        .quad   0x874621f4d86bc9ab
+        .quad   0xb54c7bbe56fe6fea
+        .quad   0x077a24257fadc22c
+        .quad   0x1ab53be419b90d39
+        .quad   0xada8b6e02946db23
+        .quad   0x1c0ce51a7b253ab7
+        .quad   0x8448c85a66dd485b
+        .quad   0x7f1fc025d0675adf
+        .quad   0xd8ee1b18319ea6aa
+        .quad   0x004d88083a21f0da
+        .quad   0x3bd6aa1d883a4f4b
+        .quad   0x4db9a3a6dfd9fd14
+
+        // 2^188 * 6 * G
+
+        .quad   0x8ce7b23bb99c0755
+        .quad   0x35c5d6edc4f50f7a
+        .quad   0x7e1e2ed2ed9b50c3
+        .quad   0x36305f16e8934da1
+        .quad   0xd95b00bbcbb77c68
+        .quad   0xddbc846a91f17849
+        .quad   0x7cf700aebe28d9b3
+        .quad   0x5ce1285c85d31f3e
+        .quad   0x31b6972d98b0bde8
+        .quad   0x7d920706aca6de5b
+        .quad   0xe67310f8908a659f
+        .quad   0x50fac2a6efdf0235
+
+        // 2^188 * 7 * G
+
+        .quad   0xf3d3a9f35b880f5a
+        .quad   0xedec050cdb03e7c2
+        .quad   0xa896981ff9f0b1a2
+        .quad   0x49a4ae2bac5e34a4
+        .quad   0x295b1c86f6f449bc
+        .quad   0x51b2e84a1f0ab4dd
+        .quad   0xc001cb30aa8e551d
+        .quad   0x6a28d35944f43662
+        .quad   0x28bb12ee04a740e0
+        .quad   0x14313bbd9bce8174
+        .quad   0x72f5b5e4e8c10c40
+        .quad   0x7cbfb19936adcd5b
+
+        // 2^188 * 8 * G
+
+        .quad   0xa311ddc26b89792d
+        .quad   0x1b30b4c6da512664
+        .quad   0x0ca77b4ccf150859
+        .quad   0x1de443df1b009408
+        .quad   0x8e793a7acc36e6e0
+        .quad   0xf9fab7a37d586eed
+        .quad   0x3a4f9692bae1f4e4
+        .quad   0x1c14b03eff5f447e
+        .quad   0x19647bd114a85291
+        .quad   0x57b76cb21034d3af
+        .quad   0x6329db440f9d6dfa
+        .quad   0x5ef43e586a571493
+
+        // 2^192 * 1 * G
+
+        .quad   0xef782014385675a6
+        .quad   0xa2649f30aafda9e8
+        .quad   0x4cd1eb505cdfa8cb
+        .quad   0x46115aba1d4dc0b3
+        .quad   0xa66dcc9dc80c1ac0
+        .quad   0x97a05cf41b38a436
+        .quad   0xa7ebf3be95dbd7c6
+        .quad   0x7da0b8f68d7e7dab
+        .quad   0xd40f1953c3b5da76
+        .quad   0x1dac6f7321119e9b
+        .quad   0x03cc6021feb25960
+        .quad   0x5a5f887e83674b4b
+
+        // 2^192 * 2 * G
+
+        .quad   0x8f6301cf70a13d11
+        .quad   0xcfceb815350dd0c4
+        .quad   0xf70297d4a4bca47e
+        .quad   0x3669b656e44d1434
+        .quad   0x9e9628d3a0a643b9
+        .quad   0xb5c3cb00e6c32064
+        .quad   0x9b5302897c2dec32
+        .quad   0x43e37ae2d5d1c70c
+        .quad   0x387e3f06eda6e133
+        .quad   0x67301d5199a13ac0
+        .quad   0xbd5ad8f836263811
+        .quad   0x6a21e6cd4fd5e9be
+
+        // 2^192 * 3 * G
+
+        .quad   0xf1c6170a3046e65f
+        .quad   0x58712a2a00d23524
+        .quad   0x69dbbd3c8c82b755
+        .quad   0x586bf9f1a195ff57
+        .quad   0xef4129126699b2e3
+        .quad   0x71d30847708d1301
+        .quad   0x325432d01182b0bd
+        .quad   0x45371b07001e8b36
+        .quad   0xa6db088d5ef8790b
+        .quad   0x5278f0dc610937e5
+        .quad   0xac0349d261a16eb8
+        .quad   0x0eafb03790e52179
+
+        // 2^192 * 4 * G
+
+        .quad   0x960555c13748042f
+        .quad   0x219a41e6820baa11
+        .quad   0x1c81f73873486d0c
+        .quad   0x309acc675a02c661
+        .quad   0x5140805e0f75ae1d
+        .quad   0xec02fbe32662cc30
+        .quad   0x2cebdf1eea92396d
+        .quad   0x44ae3344c5435bb3
+        .quad   0x9cf289b9bba543ee
+        .quad   0xf3760e9d5ac97142
+        .quad   0x1d82e5c64f9360aa
+        .quad   0x62d5221b7f94678f
+
+        // 2^192 * 5 * G
+
+        .quad   0x524c299c18d0936d
+        .quad   0xc86bb56c8a0c1a0c
+        .quad   0xa375052edb4a8631
+        .quad   0x5c0efde4bc754562
+        .quad   0x7585d4263af77a3c
+        .quad   0xdfae7b11fee9144d
+        .quad   0xa506708059f7193d
+        .quad   0x14f29a5383922037
+        .quad   0xdf717edc25b2d7f5
+        .quad   0x21f970db99b53040
+        .quad   0xda9234b7c3ed4c62
+        .quad   0x5e72365c7bee093e
+
+        // 2^192 * 6 * G
+
+        .quad   0x575bfc074571217f
+        .quad   0x3779675d0694d95b
+        .quad   0x9a0a37bbf4191e33
+        .quad   0x77f1104c47b4eabc
+        .quad   0x7d9339062f08b33e
+        .quad   0x5b9659e5df9f32be
+        .quad   0xacff3dad1f9ebdfd
+        .quad   0x70b20555cb7349b7
+        .quad   0xbe5113c555112c4c
+        .quad   0x6688423a9a881fcd
+        .quad   0x446677855e503b47
+        .quad   0x0e34398f4a06404a
+
+        // 2^192 * 7 * G
+
+        .quad   0xb67d22d93ecebde8
+        .quad   0x09b3e84127822f07
+        .quad   0x743fa61fb05b6d8d
+        .quad   0x5e5405368a362372
+        .quad   0x18930b093e4b1928
+        .quad   0x7de3e10e73f3f640
+        .quad   0xf43217da73395d6f
+        .quad   0x6f8aded6ca379c3e
+        .quad   0xe340123dfdb7b29a
+        .quad   0x487b97e1a21ab291
+        .quad   0xf9967d02fde6949e
+        .quad   0x780de72ec8d3de97
+
+        // 2^192 * 8 * G
+
+        .quad   0x0ae28545089ae7bc
+        .quad   0x388ddecf1c7f4d06
+        .quad   0x38ac15510a4811b8
+        .quad   0x0eb28bf671928ce4
+        .quad   0x671feaf300f42772
+        .quad   0x8f72eb2a2a8c41aa
+        .quad   0x29a17fd797373292
+        .quad   0x1defc6ad32b587a6
+        .quad   0xaf5bbe1aef5195a7
+        .quad   0x148c1277917b15ed
+        .quad   0x2991f7fb7ae5da2e
+        .quad   0x467d201bf8dd2867
+
+        // 2^196 * 1 * G
+
+        .quad   0x7906ee72f7bd2e6b
+        .quad   0x05d270d6109abf4e
+        .quad   0x8d5cfe45b941a8a4
+        .quad   0x44c218671c974287
+        .quad   0x745f9d56296bc318
+        .quad   0x993580d4d8152e65
+        .quad   0xb0e5b13f5839e9ce
+        .quad   0x51fc2b28d43921c0
+        .quad   0x1b8fd11795e2a98c
+        .quad   0x1c4e5ee12b6b6291
+        .quad   0x5b30e7107424b572
+        .quad   0x6e6b9de84c4f4ac6
+
+        // 2^196 * 2 * G
+
+        .quad   0xdff25fce4b1de151
+        .quad   0xd841c0c7e11c4025
+        .quad   0x2554b3c854749c87
+        .quad   0x2d292459908e0df9
+        .quad   0x6b7c5f10f80cb088
+        .quad   0x736b54dc56e42151
+        .quad   0xc2b620a5c6ef99c4
+        .quad   0x5f4c802cc3a06f42
+        .quad   0x9b65c8f17d0752da
+        .quad   0x881ce338c77ee800
+        .quad   0xc3b514f05b62f9e3
+        .quad   0x66ed5dd5bec10d48
+
+        // 2^196 * 3 * G
+
+        .quad   0x7d38a1c20bb2089d
+        .quad   0x808334e196ccd412
+        .quad   0xc4a70b8c6c97d313
+        .quad   0x2eacf8bc03007f20
+        .quad   0xf0adf3c9cbca047d
+        .quad   0x81c3b2cbf4552f6b
+        .quad   0xcfda112d44735f93
+        .quad   0x1f23a0c77e20048c
+        .quad   0xf235467be5bc1570
+        .quad   0x03d2d9020dbab38c
+        .quad   0x27529aa2fcf9e09e
+        .quad   0x0840bef29d34bc50
+
+        // 2^196 * 4 * G
+
+        .quad   0x796dfb35dc10b287
+        .quad   0x27176bcd5c7ff29d
+        .quad   0x7f3d43e8c7b24905
+        .quad   0x0304f5a191c54276
+        .quad   0xcd54e06b7f37e4eb
+        .quad   0x8cc15f87f5e96cca
+        .quad   0xb8248bb0d3597dce
+        .quad   0x246affa06074400c
+        .quad   0x37d88e68fbe45321
+        .quad   0x86097548c0d75032
+        .quad   0x4e9b13ef894a0d35
+        .quad   0x25a83cac5753d325
+
+        // 2^196 * 5 * G
+
+        .quad   0x10222f48eed8165e
+        .quad   0x623fc1234b8bcf3a
+        .quad   0x1e145c09c221e8f0
+        .quad   0x7ccfa59fca782630
+        .quad   0x9f0f66293952b6e2
+        .quad   0x33db5e0e0934267b
+        .quad   0xff45252bd609fedc
+        .quad   0x06be10f5c506e0c9
+        .quad   0x1a9615a9b62a345f
+        .quad   0x22050c564a52fecc
+        .quad   0xa7a2788528bc0dfe
+        .quad   0x5e82770a1a1ee71d
+
+        // 2^196 * 6 * G
+
+        .quad   0x35425183ad896a5c
+        .quad   0xe8673afbe78d52f6
+        .quad   0x2c66f25f92a35f64
+        .quad   0x09d04f3b3b86b102
+        .quad   0xe802e80a42339c74
+        .quad   0x34175166a7fffae5
+        .quad   0x34865d1f1c408cae
+        .quad   0x2cca982c605bc5ee
+        .quad   0xfd2d5d35197dbe6e
+        .quad   0x207c2eea8be4ffa3
+        .quad   0x2613d8db325ae918
+        .quad   0x7a325d1727741d3e
+
+        // 2^196 * 7 * G
+
+        .quad   0xd036b9bbd16dfde2
+        .quad   0xa2055757c497a829
+        .quad   0x8e6cc966a7f12667
+        .quad   0x4d3b1a791239c180
+        .quad   0xecd27d017e2a076a
+        .quad   0xd788689f1636495e
+        .quad   0x52a61af0919233e5
+        .quad   0x2a479df17bb1ae64
+        .quad   0x9e5eee8e33db2710
+        .quad   0x189854ded6c43ca5
+        .quad   0xa41c22c592718138
+        .quad   0x27ad5538a43a5e9b
+
+        // 2^196 * 8 * G
+
+        .quad   0x2746dd4b15350d61
+        .quad   0xd03fcbc8ee9521b7
+        .quad   0xe86e365a138672ca
+        .quad   0x510e987f7e7d89e2
+        .quad   0xcb5a7d638e47077c
+        .quad   0x8db7536120a1c059
+        .quad   0x549e1e4d8bedfdcc
+        .quad   0x080153b7503b179d
+        .quad   0xdda69d930a3ed3e3
+        .quad   0x3d386ef1cd60a722
+        .quad   0xc817ad58bdaa4ee6
+        .quad   0x23be8d554fe7372a
+
+        // 2^200 * 1 * G
+
+        .quad   0x95fe919a74ef4fad
+        .quad   0x3a827becf6a308a2
+        .quad   0x964e01d309a47b01
+        .quad   0x71c43c4f5ba3c797
+        .quad   0xbc1ef4bd567ae7a9
+        .quad   0x3f624cb2d64498bd
+        .quad   0xe41064d22c1f4ec8
+        .quad   0x2ef9c5a5ba384001
+        .quad   0xb6fd6df6fa9e74cd
+        .quad   0xf18278bce4af267a
+        .quad   0x8255b3d0f1ef990e
+        .quad   0x5a758ca390c5f293
+
+        // 2^200 * 2 * G
+
+        .quad   0xa2b72710d9462495
+        .quad   0x3aa8c6d2d57d5003
+        .quad   0xe3d400bfa0b487ca
+        .quad   0x2dbae244b3eb72ec
+        .quad   0x8ce0918b1d61dc94
+        .quad   0x8ded36469a813066
+        .quad   0xd4e6a829afe8aad3
+        .quad   0x0a738027f639d43f
+        .quad   0x980f4a2f57ffe1cc
+        .quad   0x00670d0de1839843
+        .quad   0x105c3f4a49fb15fd
+        .quad   0x2698ca635126a69c
+
+        // 2^200 * 3 * G
+
+        .quad   0xe765318832b0ba78
+        .quad   0x381831f7925cff8b
+        .quad   0x08a81b91a0291fcc
+        .quad   0x1fb43dcc49caeb07
+        .quad   0x2e3d702f5e3dd90e
+        .quad   0x9e3f0918e4d25386
+        .quad   0x5e773ef6024da96a
+        .quad   0x3c004b0c4afa3332
+        .quad   0x9aa946ac06f4b82b
+        .quad   0x1ca284a5a806c4f3
+        .quad   0x3ed3265fc6cd4787
+        .quad   0x6b43fd01cd1fd217
+
+        // 2^200 * 4 * G
+
+        .quad   0xc7a75d4b4697c544
+        .quad   0x15fdf848df0fffbf
+        .quad   0x2868b9ebaa46785a
+        .quad   0x5a68d7105b52f714
+        .quad   0xb5c742583e760ef3
+        .quad   0x75dc52b9ee0ab990
+        .quad   0xbf1427c2072b923f
+        .quad   0x73420b2d6ff0d9f0
+        .quad   0xaf2cf6cb9e851e06
+        .quad   0x8f593913c62238c4
+        .quad   0xda8ab89699fbf373
+        .quad   0x3db5632fea34bc9e
+
+        // 2^200 * 5 * G
+
+        .quad   0xf46eee2bf75dd9d8
+        .quad   0x0d17b1f6396759a5
+        .quad   0x1bf2d131499e7273
+        .quad   0x04321adf49d75f13
+        .quad   0x2e4990b1829825d5
+        .quad   0xedeaeb873e9a8991
+        .quad   0xeef03d394c704af8
+        .quad   0x59197ea495df2b0e
+        .quad   0x04e16019e4e55aae
+        .quad   0xe77b437a7e2f92e9
+        .quad   0xc7ce2dc16f159aa4
+        .quad   0x45eafdc1f4d70cc0
+
+        // 2^200 * 6 * G
+
+        .quad   0x698401858045d72b
+        .quad   0x4c22faa2cf2f0651
+        .quad   0x941a36656b222dc6
+        .quad   0x5a5eebc80362dade
+        .quad   0xb60e4624cfccb1ed
+        .quad   0x59dbc292bd5c0395
+        .quad   0x31a09d1ddc0481c9
+        .quad   0x3f73ceea5d56d940
+        .quad   0xb7a7bfd10a4e8dc6
+        .quad   0xbe57007e44c9b339
+        .quad   0x60c1207f1557aefa
+        .quad   0x26058891266218db
+
+        // 2^200 * 7 * G
+
+        .quad   0x59f704a68360ff04
+        .quad   0xc3d93fde7661e6f4
+        .quad   0x831b2a7312873551
+        .quad   0x54ad0c2e4e615d57
+        .quad   0x4c818e3cc676e542
+        .quad   0x5e422c9303ceccad
+        .quad   0xec07cccab4129f08
+        .quad   0x0dedfa10b24443b8
+        .quad   0xee3b67d5b82b522a
+        .quad   0x36f163469fa5c1eb
+        .quad   0xa5b4d2f26ec19fd3
+        .quad   0x62ecb2baa77a9408
+
+        // 2^200 * 8 * G
+
+        .quad   0xe5ed795261152b3d
+        .quad   0x4962357d0eddd7d1
+        .quad   0x7482c8d0b96b4c71
+        .quad   0x2e59f919a966d8be
+        .quad   0x92072836afb62874
+        .quad   0x5fcd5e8579e104a5
+        .quad   0x5aad01adc630a14a
+        .quad   0x61913d5075663f98
+        .quad   0x0dc62d361a3231da
+        .quad   0xfa47583294200270
+        .quad   0x02d801513f9594ce
+        .quad   0x3ddbc2a131c05d5c
+
+        // 2^204 * 1 * G
+
+        .quad   0x3f50a50a4ffb81ef
+        .quad   0xb1e035093bf420bf
+        .quad   0x9baa8e1cc6aa2cd0
+        .quad   0x32239861fa237a40
+        .quad   0xfb735ac2004a35d1
+        .quad   0x31de0f433a6607c3
+        .quad   0x7b8591bfc528d599
+        .quad   0x55be9a25f5bb050c
+        .quad   0x0d005acd33db3dbf
+        .quad   0x0111b37c80ac35e2
+        .quad   0x4892d66c6f88ebeb
+        .quad   0x770eadb16508fbcd
+
+        // 2^204 * 2 * G
+
+        .quad   0x8451f9e05e4e89dd
+        .quad   0xc06302ffbc793937
+        .quad   0x5d22749556a6495c
+        .quad   0x09a6755ca05603fb
+        .quad   0xf1d3b681a05071b9
+        .quad   0x2207659a3592ff3a
+        .quad   0x5f0169297881e40e
+        .quad   0x16bedd0e86ba374e
+        .quad   0x5ecccc4f2c2737b5
+        .quad   0x43b79e0c2dccb703
+        .quad   0x33e008bc4ec43df3
+        .quad   0x06c1b840f07566c0
+
+        // 2^204 * 3 * G
+
+        .quad   0x7688a5c6a388f877
+        .quad   0x02a96c14deb2b6ac
+        .quad   0x64c9f3431b8c2af8
+        .quad   0x3628435554a1eed6
+        .quad   0x69ee9e7f9b02805c
+        .quad   0xcbff828a547d1640
+        .quad   0x3d93a869b2430968
+        .quad   0x46b7b8cd3fe26972
+        .quad   0xe9812086fe7eebe0
+        .quad   0x4cba6be72f515437
+        .quad   0x1d04168b516efae9
+        .quad   0x5ea1391043982cb9
+
+        // 2^204 * 4 * G
+
+        .quad   0x49125c9cf4702ee1
+        .quad   0x4520b71f8b25b32d
+        .quad   0x33193026501fef7e
+        .quad   0x656d8997c8d2eb2b
+        .quad   0x6f2b3be4d5d3b002
+        .quad   0xafec33d96a09c880
+        .quad   0x035f73a4a8bcc4cc
+        .quad   0x22c5b9284662198b
+        .quad   0xcb58c8fe433d8939
+        .quad   0x89a0cb2e6a8d7e50
+        .quad   0x79ca955309fbbe5a
+        .quad   0x0c626616cd7fc106
+
+        // 2^204 * 5 * G
+
+        .quad   0x1ffeb80a4879b61f
+        .quad   0x6396726e4ada21ed
+        .quad   0x33c7b093368025ba
+        .quad   0x471aa0c6f3c31788
+        .quad   0x8fdfc379fbf454b1
+        .quad   0x45a5a970f1a4b771
+        .quad   0xac921ef7bad35915
+        .quad   0x42d088dca81c2192
+        .quad   0x8fda0f37a0165199
+        .quad   0x0adadb77c8a0e343
+        .quad   0x20fbfdfcc875e820
+        .quad   0x1cf2bea80c2206e7
+
+        // 2^204 * 6 * G
+
+        .quad   0xc2ddf1deb36202ac
+        .quad   0x92a5fe09d2e27aa5
+        .quad   0x7d1648f6fc09f1d3
+        .quad   0x74c2cc0513bc4959
+        .quad   0x982d6e1a02c0412f
+        .quad   0x90fa4c83db58e8fe
+        .quad   0x01c2f5bcdcb18bc0
+        .quad   0x686e0c90216abc66
+        .quad   0x1fadbadba54395a7
+        .quad   0xb41a02a0ae0da66a
+        .quad   0xbf19f598bba37c07
+        .quad   0x6a12b8acde48430d
+
+        // 2^204 * 7 * G
+
+        .quad   0xf8daea1f39d495d9
+        .quad   0x592c190e525f1dfc
+        .quad   0xdb8cbd04c9991d1b
+        .quad   0x11f7fda3d88f0cb7
+        .quad   0x793bdd801aaeeb5f
+        .quad   0x00a2a0aac1518871
+        .quad   0xe8a373a31f2136b4
+        .quad   0x48aab888fc91ef19
+        .quad   0x041f7e925830f40e
+        .quad   0x002d6ca979661c06
+        .quad   0x86dc9ff92b046a2e
+        .quad   0x760360928b0493d1
+
+        // 2^204 * 8 * G
+
+        .quad   0x21bb41c6120cf9c6
+        .quad   0xeab2aa12decda59b
+        .quad   0xc1a72d020aa48b34
+        .quad   0x215d4d27e87d3b68
+        .quad   0xb43108e5695a0b05
+        .quad   0x6cb00ee8ad37a38b
+        .quad   0x5edad6eea3537381
+        .quad   0x3f2602d4b6dc3224
+        .quad   0xc8b247b65bcaf19c
+        .quad   0x49779dc3b1b2c652
+        .quad   0x89a180bbd5ece2e2
+        .quad   0x13f098a3cec8e039
+
+        // 2^208 * 1 * G
+
+        .quad   0x9adc0ff9ce5ec54b
+        .quad   0x039c2a6b8c2f130d
+        .quad   0x028007c7f0f89515
+        .quad   0x78968314ac04b36b
+        .quad   0xf3aa57a22796bb14
+        .quad   0x883abab79b07da21
+        .quad   0xe54be21831a0391c
+        .quad   0x5ee7fb38d83205f9
+        .quad   0x538dfdcb41446a8e
+        .quad   0xa5acfda9434937f9
+        .quad   0x46af908d263c8c78
+        .quad   0x61d0633c9bca0d09
+
+        // 2^208 * 2 * G
+
+        .quad   0x63744935ffdb2566
+        .quad   0xc5bd6b89780b68bb
+        .quad   0x6f1b3280553eec03
+        .quad   0x6e965fd847aed7f5
+        .quad   0xada328bcf8fc73df
+        .quad   0xee84695da6f037fc
+        .quad   0x637fb4db38c2a909
+        .quad   0x5b23ac2df8067bdc
+        .quad   0x9ad2b953ee80527b
+        .quad   0xe88f19aafade6d8d
+        .quad   0x0e711704150e82cf
+        .quad   0x79b9bbb9dd95dedc
+
+        // 2^208 * 3 * G
+
+        .quad   0xebb355406a3126c2
+        .quad   0xd26383a868c8c393
+        .quad   0x6c0c6429e5b97a82
+        .quad   0x5065f158c9fd2147
+        .quad   0xd1997dae8e9f7374
+        .quad   0xa032a2f8cfbb0816
+        .quad   0xcd6cba126d445f0a
+        .quad   0x1ba811460accb834
+        .quad   0x708169fb0c429954
+        .quad   0xe14600acd76ecf67
+        .quad   0x2eaab98a70e645ba
+        .quad   0x3981f39e58a4faf2
+
+        // 2^208 * 4 * G
+
+        .quad   0x18fb8a7559230a93
+        .quad   0x1d168f6960e6f45d
+        .quad   0x3a85a94514a93cb5
+        .quad   0x38dc083705acd0fd
+        .quad   0xc845dfa56de66fde
+        .quad   0xe152a5002c40483a
+        .quad   0xe9d2e163c7b4f632
+        .quad   0x30f4452edcbc1b65
+        .quad   0x856d2782c5759740
+        .quad   0xfa134569f99cbecc
+        .quad   0x8844fc73c0ea4e71
+        .quad   0x632d9a1a593f2469
+
+        // 2^208 * 5 * G
+
+        .quad   0xf6bb6b15b807cba6
+        .quad   0x1823c7dfbc54f0d7
+        .quad   0xbb1d97036e29670b
+        .quad   0x0b24f48847ed4a57
+        .quad   0xbf09fd11ed0c84a7
+        .quad   0x63f071810d9f693a
+        .quad   0x21908c2d57cf8779
+        .quad   0x3a5a7df28af64ba2
+        .quad   0xdcdad4be511beac7
+        .quad   0xa4538075ed26ccf2
+        .quad   0xe19cff9f005f9a65
+        .quad   0x34fcf74475481f63
+
+        // 2^208 * 6 * G
+
+        .quad   0xc197e04c789767ca
+        .quad   0xb8714dcb38d9467d
+        .quad   0x55de888283f95fa8
+        .quad   0x3d3bdc164dfa63f7
+        .quad   0xa5bb1dab78cfaa98
+        .quad   0x5ceda267190b72f2
+        .quad   0x9309c9110a92608e
+        .quad   0x0119a3042fb374b0
+        .quad   0x67a2d89ce8c2177d
+        .quad   0x669da5f66895d0c1
+        .quad   0xf56598e5b282a2b0
+        .quad   0x56c088f1ede20a73
+
+        // 2^208 * 7 * G
+
+        .quad   0x336d3d1110a86e17
+        .quad   0xd7f388320b75b2fa
+        .quad   0xf915337625072988
+        .quad   0x09674c6b99108b87
+        .quad   0x581b5fac24f38f02
+        .quad   0xa90be9febae30cbd
+        .quad   0x9a2169028acf92f0
+        .quad   0x038b7ea48359038f
+        .quad   0x9f4ef82199316ff8
+        .quad   0x2f49d282eaa78d4f
+        .quad   0x0971a5ab5aef3174
+        .quad   0x6e5e31025969eb65
+
+        // 2^208 * 8 * G
+
+        .quad   0xb16c62f587e593fb
+        .quad   0x4999eddeca5d3e71
+        .quad   0xb491c1e014cc3e6d
+        .quad   0x08f5114789a8dba8
+        .quad   0x3304fb0e63066222
+        .quad   0xfb35068987acba3f
+        .quad   0xbd1924778c1061a3
+        .quad   0x3058ad43d1838620
+        .quad   0x323c0ffde57663d0
+        .quad   0x05c3df38a22ea610
+        .quad   0xbdc78abdac994f9a
+        .quad   0x26549fa4efe3dc99
+
+        // 2^212 * 1 * G
+
+        .quad   0x738b38d787ce8f89
+        .quad   0xb62658e24179a88d
+        .quad   0x30738c9cf151316d
+        .quad   0x49128c7f727275c9
+        .quad   0x04dbbc17f75396b9
+        .quad   0x69e6a2d7d2f86746
+        .quad   0xc6409d99f53eabc6
+        .quad   0x606175f6332e25d2
+        .quad   0x4021370ef540e7dd
+        .quad   0x0910d6f5a1f1d0a5
+        .quad   0x4634aacd5b06b807
+        .quad   0x6a39e6356944f235
+
+        // 2^212 * 2 * G
+
+        .quad   0x96cd5640df90f3e7
+        .quad   0x6c3a760edbfa25ea
+        .quad   0x24f3ef0959e33cc4
+        .quad   0x42889e7e530d2e58
+        .quad   0x1da1965774049e9d
+        .quad   0xfbcd6ea198fe352b
+        .quad   0xb1cbcd50cc5236a6
+        .quad   0x1f5ec83d3f9846e2
+        .quad   0x8efb23c3328ccb75
+        .quad   0xaf42a207dd876ee9
+        .quad   0x20fbdadc5dfae796
+        .quad   0x241e246b06bf9f51
+
+        // 2^212 * 3 * G
+
+        .quad   0x29e68e57ad6e98f6
+        .quad   0x4c9260c80b462065
+        .quad   0x3f00862ea51ebb4b
+        .quad   0x5bc2c77fb38d9097
+        .quad   0x7eaafc9a6280bbb8
+        .quad   0x22a70f12f403d809
+        .quad   0x31ce40bb1bfc8d20
+        .quad   0x2bc65635e8bd53ee
+        .quad   0xe8d5dc9fa96bad93
+        .quad   0xe58fb17dde1947dc
+        .quad   0x681532ea65185fa3
+        .quad   0x1fdd6c3b034a7830
+
+        // 2^212 * 4 * G
+
+        .quad   0x0a64e28c55dc18fe
+        .quad   0xe3df9e993399ebdd
+        .quad   0x79ac432370e2e652
+        .quad   0x35ff7fc33ae4cc0e
+        .quad   0x9c13a6a52dd8f7a9
+        .quad   0x2dbb1f8c3efdcabf
+        .quad   0x961e32405e08f7b5
+        .quad   0x48c8a121bbe6c9e5
+        .quad   0xfc415a7c59646445
+        .quad   0xd224b2d7c128b615
+        .quad   0x6035c9c905fbb912
+        .quad   0x42d7a91274429fab
+
+        // 2^212 * 5 * G
+
+        .quad   0x4e6213e3eaf72ed3
+        .quad   0x6794981a43acd4e7
+        .quad   0xff547cde6eb508cb
+        .quad   0x6fed19dd10fcb532
+        .quad   0xa9a48947933da5bc
+        .quad   0x4a58920ec2e979ec
+        .quad   0x96d8800013e5ac4c
+        .quad   0x453692d74b48b147
+        .quad   0xdd775d99a8559c6f
+        .quad   0xf42a2140df003e24
+        .quad   0x5223e229da928a66
+        .quad   0x063f46ba6d38f22c
+
+        // 2^212 * 6 * G
+
+        .quad   0xd2d242895f536694
+        .quad   0xca33a2c542939b2c
+        .quad   0x986fada6c7ddb95c
+        .quad   0x5a152c042f712d5d
+        .quad   0x39843cb737346921
+        .quad   0xa747fb0738c89447
+        .quad   0xcb8d8031a245307e
+        .quad   0x67810f8e6d82f068
+        .quad   0x3eeb8fbcd2287db4
+        .quad   0x72c7d3a301a03e93
+        .quad   0x5473e88cbd98265a
+        .quad   0x7324aa515921b403
+
+        // 2^212 * 7 * G
+
+        .quad   0x857942f46c3cbe8e
+        .quad   0xa1d364b14730c046
+        .quad   0x1c8ed914d23c41bf
+        .quad   0x0838e161eef6d5d2
+        .quad   0xad23f6dae82354cb
+        .quad   0x6962502ab6571a6d
+        .quad   0x9b651636e38e37d1
+        .quad   0x5cac5005d1a3312f
+        .quad   0x8cc154cce9e39904
+        .quad   0x5b3a040b84de6846
+        .quad   0xc4d8a61cb1be5d6e
+        .quad   0x40fb897bd8861f02
+
+        // 2^212 * 8 * G
+
+        .quad   0x84c5aa9062de37a1
+        .quad   0x421da5000d1d96e1
+        .quad   0x788286306a9242d9
+        .quad   0x3c5e464a690d10da
+        .quad   0xe57ed8475ab10761
+        .quad   0x71435e206fd13746
+        .quad   0x342f824ecd025632
+        .quad   0x4b16281ea8791e7b
+        .quad   0xd1c101d50b813381
+        .quad   0xdee60f1176ee6828
+        .quad   0x0cb68893383f6409
+        .quad   0x6183c565f6ff484a
+
+        // 2^216 * 1 * G
+
+        .quad   0x741d5a461e6bf9d6
+        .quad   0x2305b3fc7777a581
+        .quad   0xd45574a26474d3d9
+        .quad   0x1926e1dc6401e0ff
+        .quad   0xdb468549af3f666e
+        .quad   0xd77fcf04f14a0ea5
+        .quad   0x3df23ff7a4ba0c47
+        .quad   0x3a10dfe132ce3c85
+        .quad   0xe07f4e8aea17cea0
+        .quad   0x2fd515463a1fc1fd
+        .quad   0x175322fd31f2c0f1
+        .quad   0x1fa1d01d861e5d15
+
+        // 2^216 * 2 * G
+
+        .quad   0xcc8055947d599832
+        .quad   0x1e4656da37f15520
+        .quad   0x99f6f7744e059320
+        .quad   0x773563bc6a75cf33
+        .quad   0x38dcac00d1df94ab
+        .quad   0x2e712bddd1080de9
+        .quad   0x7f13e93efdd5e262
+        .quad   0x73fced18ee9a01e5
+        .quad   0x06b1e90863139cb3
+        .quad   0xa493da67c5a03ecd
+        .quad   0x8d77cec8ad638932
+        .quad   0x1f426b701b864f44
+
+        // 2^216 * 3 * G
+
+        .quad   0xefc9264c41911c01
+        .quad   0xf1a3b7b817a22c25
+        .quad   0x5875da6bf30f1447
+        .quad   0x4e1af5271d31b090
+        .quad   0xf17e35c891a12552
+        .quad   0xb76b8153575e9c76
+        .quad   0xfa83406f0d9b723e
+        .quad   0x0b76bb1b3fa7e438
+        .quad   0x08b8c1f97f92939b
+        .quad   0xbe6771cbd444ab6e
+        .quad   0x22e5646399bb8017
+        .quad   0x7b6dd61eb772a955
+
+        // 2^216 * 4 * G
+
+        .quad   0xb7adc1e850f33d92
+        .quad   0x7998fa4f608cd5cf
+        .quad   0xad962dbd8dfc5bdb
+        .quad   0x703e9bceaf1d2f4f
+        .quad   0x5730abf9ab01d2c7
+        .quad   0x16fb76dc40143b18
+        .quad   0x866cbe65a0cbb281
+        .quad   0x53fa9b659bff6afe
+        .quad   0x6c14c8e994885455
+        .quad   0x843a5d6665aed4e5
+        .quad   0x181bb73ebcd65af1
+        .quad   0x398d93e5c4c61f50
+
+        // 2^216 * 5 * G
+
+        .quad   0x1c4bd16733e248f3
+        .quad   0xbd9e128715bf0a5f
+        .quad   0xd43f8cf0a10b0376
+        .quad   0x53b09b5ddf191b13
+        .quad   0xc3877c60d2e7e3f2
+        .quad   0x3b34aaa030828bb1
+        .quad   0x283e26e7739ef138
+        .quad   0x699c9c9002c30577
+        .quad   0xf306a7235946f1cc
+        .quad   0x921718b5cce5d97d
+        .quad   0x28cdd24781b4e975
+        .quad   0x51caf30c6fcdd907
+
+        // 2^216 * 6 * G
+
+        .quad   0xa60ba7427674e00a
+        .quad   0x630e8570a17a7bf3
+        .quad   0x3758563dcf3324cc
+        .quad   0x5504aa292383fdaa
+        .quad   0x737af99a18ac54c7
+        .quad   0x903378dcc51cb30f
+        .quad   0x2b89bc334ce10cc7
+        .quad   0x12ae29c189f8e99a
+        .quad   0xa99ec0cb1f0d01cf
+        .quad   0x0dd1efcc3a34f7ae
+        .quad   0x55ca7521d09c4e22
+        .quad   0x5fd14fe958eba5ea
+
+        // 2^216 * 7 * G
+
+        .quad   0xb5dc2ddf2845ab2c
+        .quad   0x069491b10a7fe993
+        .quad   0x4daaf3d64002e346
+        .quad   0x093ff26e586474d1
+        .quad   0x3c42fe5ebf93cb8e
+        .quad   0xbedfa85136d4565f
+        .quad   0xe0f0859e884220e8
+        .quad   0x7dd73f960725d128
+        .quad   0xb10d24fe68059829
+        .quad   0x75730672dbaf23e5
+        .quad   0x1367253ab457ac29
+        .quad   0x2f59bcbc86b470a4
+
+        // 2^216 * 8 * G
+
+        .quad   0x83847d429917135f
+        .quad   0xad1b911f567d03d7
+        .quad   0x7e7748d9be77aad1
+        .quad   0x5458b42e2e51af4a
+        .quad   0x7041d560b691c301
+        .quad   0x85201b3fadd7e71e
+        .quad   0x16c2e16311335585
+        .quad   0x2aa55e3d010828b1
+        .quad   0xed5192e60c07444f
+        .quad   0x42c54e2d74421d10
+        .quad   0x352b4c82fdb5c864
+        .quad   0x13e9004a8a768664
+
+        // 2^220 * 1 * G
+
+        .quad   0xcbb5b5556c032bff
+        .quad   0xdf7191b729297a3a
+        .quad   0xc1ff7326aded81bb
+        .quad   0x71ade8bb68be03f5
+        .quad   0x1e6284c5806b467c
+        .quad   0xc5f6997be75d607b
+        .quad   0x8b67d958b378d262
+        .quad   0x3d88d66a81cd8b70
+        .quad   0x8b767a93204ed789
+        .quad   0x762fcacb9fa0ae2a
+        .quad   0x771febcc6dce4887
+        .quad   0x343062158ff05fb3
+
+        // 2^220 * 2 * G
+
+        .quad   0xe05da1a7e1f5bf49
+        .quad   0x26457d6dd4736092
+        .quad   0x77dcb07773cc32f6
+        .quad   0x0a5d94969cdd5fcd
+        .quad   0xfce219072a7b31b4
+        .quad   0x4d7adc75aa578016
+        .quad   0x0ec276a687479324
+        .quad   0x6d6d9d5d1fda4beb
+        .quad   0x22b1a58ae9b08183
+        .quad   0xfd95d071c15c388b
+        .quad   0xa9812376850a0517
+        .quad   0x33384cbabb7f335e
+
+        // 2^220 * 3 * G
+
+        .quad   0x3c6fa2680ca2c7b5
+        .quad   0x1b5082046fb64fda
+        .quad   0xeb53349c5431d6de
+        .quad   0x5278b38f6b879c89
+        .quad   0x33bc627a26218b8d
+        .quad   0xea80b21fc7a80c61
+        .quad   0x9458b12b173e9ee6
+        .quad   0x076247be0e2f3059
+        .quad   0x52e105f61416375a
+        .quad   0xec97af3685abeba4
+        .quad   0x26e6b50623a67c36
+        .quad   0x5cf0e856f3d4fb01
+
+        // 2^220 * 4 * G
+
+        .quad   0xf6c968731ae8cab4
+        .quad   0x5e20741ecb4f92c5
+        .quad   0x2da53be58ccdbc3e
+        .quad   0x2dddfea269970df7
+        .quad   0xbeaece313db342a8
+        .quad   0xcba3635b842db7ee
+        .quad   0xe88c6620817f13ef
+        .quad   0x1b9438aa4e76d5c6
+        .quad   0x8a50777e166f031a
+        .quad   0x067b39f10fb7a328
+        .quad   0x1925c9a6010fbd76
+        .quad   0x6df9b575cc740905
+
+        // 2^220 * 5 * G
+
+        .quad   0x42c1192927f6bdcf
+        .quad   0x8f91917a403d61ca
+        .quad   0xdc1c5a668b9e1f61
+        .quad   0x1596047804ec0f8d
+        .quad   0xecdfc35b48cade41
+        .quad   0x6a88471fb2328270
+        .quad   0x740a4a2440a01b6a
+        .quad   0x471e5796003b5f29
+        .quad   0xda96bbb3aced37ac
+        .quad   0x7a2423b5e9208cea
+        .quad   0x24cc5c3038aebae2
+        .quad   0x50c356afdc5dae2f
+
+        // 2^220 * 6 * G
+
+        .quad   0x09dcbf4341c30318
+        .quad   0xeeba061183181dce
+        .quad   0xc179c0cedc1e29a1
+        .quad   0x1dbf7b89073f35b0
+        .quad   0xcfed9cdf1b31b964
+        .quad   0xf486a9858ca51af3
+        .quad   0x14897265ea8c1f84
+        .quad   0x784a53dd932acc00
+        .quad   0x2d99f9df14fc4920
+        .quad   0x76ccb60cc4499fe5
+        .quad   0xa4132cbbe5cf0003
+        .quad   0x3f93d82354f000ea
+
+        // 2^220 * 7 * G
+
+        .quad   0x8183e7689e04ce85
+        .quad   0x678fb71e04465341
+        .quad   0xad92058f6688edac
+        .quad   0x5da350d3532b099a
+        .quad   0xeaac12d179e14978
+        .quad   0xff923ff3bbebff5e
+        .quad   0x4af663e40663ce27
+        .quad   0x0fd381a811a5f5ff
+        .quad   0xf256aceca436df54
+        .quad   0x108b6168ae69d6e8
+        .quad   0x20d986cb6b5d036c
+        .quad   0x655957b9fee2af50
+
+        // 2^220 * 8 * G
+
+        .quad   0xaea8b07fa902030f
+        .quad   0xf88c766af463d143
+        .quad   0x15b083663c787a60
+        .quad   0x08eab1148267a4a8
+        .quad   0xbdc1409bd002d0ac
+        .quad   0x66660245b5ccd9a6
+        .quad   0x82317dc4fade85ec
+        .quad   0x02fe934b6ad7df0d
+        .quad   0xef5cf100cfb7ea74
+        .quad   0x22897633a1cb42ac
+        .quad   0xd4ce0c54cef285e2
+        .quad   0x30408c048a146a55
+
+        // 2^224 * 1 * G
+
+        .quad   0x739d8845832fcedb
+        .quad   0xfa38d6c9ae6bf863
+        .quad   0x32bc0dcab74ffef7
+        .quad   0x73937e8814bce45e
+        .quad   0xbb2e00c9193b877f
+        .quad   0xece3a890e0dc506b
+        .quad   0xecf3b7c036de649f
+        .quad   0x5f46040898de9e1a
+        .quad   0xb9037116297bf48d
+        .quad   0xa9d13b22d4f06834
+        .quad   0xe19715574696bdc6
+        .quad   0x2cf8a4e891d5e835
+
+        // 2^224 * 2 * G
+
+        .quad   0x6d93fd8707110f67
+        .quad   0xdd4c09d37c38b549
+        .quad   0x7cb16a4cc2736a86
+        .quad   0x2049bd6e58252a09
+        .quad   0x2cb5487e17d06ba2
+        .quad   0x24d2381c3950196b
+        .quad   0xd7659c8185978a30
+        .quad   0x7a6f7f2891d6a4f6
+        .quad   0x7d09fd8d6a9aef49
+        .quad   0xf0ee60be5b3db90b
+        .quad   0x4c21b52c519ebfd4
+        .quad   0x6011aadfc545941d
+
+        // 2^224 * 3 * G
+
+        .quad   0x5f67926dcf95f83c
+        .quad   0x7c7e856171289071
+        .quad   0xd6a1e7f3998f7a5b
+        .quad   0x6fc5cc1b0b62f9e0
+        .quad   0x63ded0c802cbf890
+        .quad   0xfbd098ca0dff6aaa
+        .quad   0x624d0afdb9b6ed99
+        .quad   0x69ce18b779340b1e
+        .quad   0xd1ef5528b29879cb
+        .quad   0xdd1aae3cd47e9092
+        .quad   0x127e0442189f2352
+        .quad   0x15596b3ae57101f1
+
+        // 2^224 * 4 * G
+
+        .quad   0x462739d23f9179a2
+        .quad   0xff83123197d6ddcf
+        .quad   0x1307deb553f2148a
+        .quad   0x0d2237687b5f4dda
+        .quad   0x09ff31167e5124ca
+        .quad   0x0be4158bd9c745df
+        .quad   0x292b7d227ef556e5
+        .quad   0x3aa4e241afb6d138
+        .quad   0x2cc138bf2a3305f5
+        .quad   0x48583f8fa2e926c3
+        .quad   0x083ab1a25549d2eb
+        .quad   0x32fcaa6e4687a36c
+
+        // 2^224 * 5 * G
+
+        .quad   0x7bc56e8dc57d9af5
+        .quad   0x3e0bd2ed9df0bdf2
+        .quad   0xaac014de22efe4a3
+        .quad   0x4627e9cefebd6a5c
+        .quad   0x3207a4732787ccdf
+        .quad   0x17e31908f213e3f8
+        .quad   0xd5b2ecd7f60d964e
+        .quad   0x746f6336c2600be9
+        .quad   0x3f4af345ab6c971c
+        .quad   0xe288eb729943731f
+        .quad   0x33596a8a0344186d
+        .quad   0x7b4917007ed66293
+
+        // 2^224 * 6 * G
+
+        .quad   0x2d85fb5cab84b064
+        .quad   0x497810d289f3bc14
+        .quad   0x476adc447b15ce0c
+        .quad   0x122ba376f844fd7b
+        .quad   0x54341b28dd53a2dd
+        .quad   0xaa17905bdf42fc3f
+        .quad   0x0ff592d94dd2f8f4
+        .quad   0x1d03620fe08cd37d
+        .quad   0xc20232cda2b4e554
+        .quad   0x9ed0fd42115d187f
+        .quad   0x2eabb4be7dd479d9
+        .quad   0x02c70bf52b68ec4c
+
+        // 2^224 * 7 * G
+
+        .quad   0xa287ec4b5d0b2fbb
+        .quad   0x415c5790074882ca
+        .quad   0xe044a61ec1d0815c
+        .quad   0x26334f0a409ef5e0
+        .quad   0xace532bf458d72e1
+        .quad   0x5be768e07cb73cb5
+        .quad   0x56cf7d94ee8bbde7
+        .quad   0x6b0697e3feb43a03
+        .quad   0xb6c8f04adf62a3c0
+        .quad   0x3ef000ef076da45d
+        .quad   0x9c9cb95849f0d2a9
+        .quad   0x1cc37f43441b2fae
+
+        // 2^224 * 8 * G
+
+        .quad   0x508f565a5cc7324f
+        .quad   0xd061c4c0e506a922
+        .quad   0xfb18abdb5c45ac19
+        .quad   0x6c6809c10380314a
+        .quad   0xd76656f1c9ceaeb9
+        .quad   0x1c5b15f818e5656a
+        .quad   0x26e72832844c2334
+        .quad   0x3a346f772f196838
+        .quad   0xd2d55112e2da6ac8
+        .quad   0xe9bd0331b1e851ed
+        .quad   0x960746dd8ec67262
+        .quad   0x05911b9f6ef7c5d0
+
+        // 2^228 * 1 * G
+
+        .quad   0xe9dcd756b637ff2d
+        .quad   0xec4c348fc987f0c4
+        .quad   0xced59285f3fbc7b7
+        .quad   0x3305354793e1ea87
+        .quad   0x01c18980c5fe9f94
+        .quad   0xcd656769716fd5c8
+        .quad   0x816045c3d195a086
+        .quad   0x6e2b7f3266cc7982
+        .quad   0xcc802468f7c3568f
+        .quad   0x9de9ba8219974cb3
+        .quad   0xabb7229cb5b81360
+        .quad   0x44e2017a6fbeba62
+
+        // 2^228 * 2 * G
+
+        .quad   0xc4c2a74354dab774
+        .quad   0x8e5d4c3c4eaf031a
+        .quad   0xb76c23d242838f17
+        .quad   0x749a098f68dce4ea
+        .quad   0x87f82cf3b6ca6ecd
+        .quad   0x580f893e18f4a0c2
+        .quad   0x058930072604e557
+        .quad   0x6cab6ac256d19c1d
+        .quad   0xdcdfe0a02cc1de60
+        .quad   0x032665ff51c5575b
+        .quad   0x2c0c32f1073abeeb
+        .quad   0x6a882014cd7b8606
+
+        // 2^228 * 3 * G
+
+        .quad   0xa52a92fea4747fb5
+        .quad   0xdc12a4491fa5ab89
+        .quad   0xd82da94bb847a4ce
+        .quad   0x4d77edce9512cc4e
+        .quad   0xd111d17caf4feb6e
+        .quad   0x050bba42b33aa4a3
+        .quad   0x17514c3ceeb46c30
+        .quad   0x54bedb8b1bc27d75
+        .quad   0x77c8e14577e2189c
+        .quad   0xa3e46f6aff99c445
+        .quad   0x3144dfc86d335343
+        .quad   0x3a96559e7c4216a9
+
+        // 2^228 * 4 * G
+
+        .quad   0x12550d37f42ad2ee
+        .quad   0x8b78e00498a1fbf5
+        .quad   0x5d53078233894cb2
+        .quad   0x02c84e4e3e498d0c
+        .quad   0x4493896880baaa52
+        .quad   0x4c98afc4f285940e
+        .quad   0xef4aa79ba45448b6
+        .quad   0x5278c510a57aae7f
+        .quad   0xa54dd074294c0b94
+        .quad   0xf55d46b8df18ffb6
+        .quad   0xf06fecc58dae8366
+        .quad   0x588657668190d165
+
+        // 2^228 * 5 * G
+
+        .quad   0xd47712311aef7117
+        .quad   0x50343101229e92c7
+        .quad   0x7a95e1849d159b97
+        .quad   0x2449959b8b5d29c9
+        .quad   0xbf5834f03de25cc3
+        .quad   0xb887c8aed6815496
+        .quad   0x5105221a9481e892
+        .quad   0x6760ed19f7723f93
+        .quad   0x669ba3b7ac35e160
+        .quad   0x2eccf73fba842056
+        .quad   0x1aec1f17c0804f07
+        .quad   0x0d96bc031856f4e7
+
+        // 2^228 * 6 * G
+
+        .quad   0x3318be7775c52d82
+        .quad   0x4cb764b554d0aab9
+        .quad   0xabcf3d27cc773d91
+        .quad   0x3bf4d1848123288a
+        .quad   0xb1d534b0cc7505e1
+        .quad   0x32cd003416c35288
+        .quad   0xcb36a5800762c29d
+        .quad   0x5bfe69b9237a0bf8
+        .quad   0x183eab7e78a151ab
+        .quad   0xbbe990c999093763
+        .quad   0xff717d6e4ac7e335
+        .quad   0x4c5cddb325f39f88
+
+        // 2^228 * 7 * G
+
+        .quad   0xc0f6b74d6190a6eb
+        .quad   0x20ea81a42db8f4e4
+        .quad   0xa8bd6f7d97315760
+        .quad   0x33b1d60262ac7c21
+        .quad   0x57750967e7a9f902
+        .quad   0x2c37fdfc4f5b467e
+        .quad   0xb261663a3177ba46
+        .quad   0x3a375e78dc2d532b
+        .quad   0x8141e72f2d4dddea
+        .quad   0xe6eafe9862c607c8
+        .quad   0x23c28458573cafd0
+        .quad   0x46b9476f4ff97346
+
+        // 2^228 * 8 * G
+
+        .quad   0x0c1ffea44f901e5c
+        .quad   0x2b0b6fb72184b782
+        .quad   0xe587ff910114db88
+        .quad   0x37130f364785a142
+        .quad   0x1215505c0d58359f
+        .quad   0x2a2013c7fc28c46b
+        .quad   0x24a0a1af89ea664e
+        .quad   0x4400b638a1130e1f
+        .quad   0x3a01b76496ed19c3
+        .quad   0x31e00ab0ed327230
+        .quad   0x520a885783ca15b1
+        .quad   0x06aab9875accbec7
+
+        // 2^232 * 1 * G
+
+        .quad   0xc1339983f5df0ebb
+        .quad   0xc0f3758f512c4cac
+        .quad   0x2cf1130a0bb398e1
+        .quad   0x6b3cecf9aa270c62
+        .quad   0x5349acf3512eeaef
+        .quad   0x20c141d31cc1cb49
+        .quad   0x24180c07a99a688d
+        .quad   0x555ef9d1c64b2d17
+        .quad   0x36a770ba3b73bd08
+        .quad   0x624aef08a3afbf0c
+        .quad   0x5737ff98b40946f2
+        .quad   0x675f4de13381749d
+
+        // 2^232 * 2 * G
+
+        .quad   0x0e2c52036b1782fc
+        .quad   0x64816c816cad83b4
+        .quad   0xd0dcbdd96964073e
+        .quad   0x13d99df70164c520
+        .quad   0xa12ff6d93bdab31d
+        .quad   0x0725d80f9d652dfe
+        .quad   0x019c4ff39abe9487
+        .quad   0x60f450b882cd3c43
+        .quad   0x014b5ec321e5c0ca
+        .quad   0x4fcb69c9d719bfa2
+        .quad   0x4e5f1c18750023a0
+        .quad   0x1c06de9e55edac80
+
+        // 2^232 * 3 * G
+
+        .quad   0x990f7ad6a33ec4e2
+        .quad   0x6608f938be2ee08e
+        .quad   0x9ca143c563284515
+        .quad   0x4cf38a1fec2db60d
+        .quad   0xffd52b40ff6d69aa
+        .quad   0x34530b18dc4049bb
+        .quad   0x5e4a5c2fa34d9897
+        .quad   0x78096f8e7d32ba2d
+        .quad   0xa0aaaa650dfa5ce7
+        .quad   0xf9c49e2a48b5478c
+        .quad   0x4f09cc7d7003725b
+        .quad   0x373cad3a26091abe
+
+        // 2^232 * 4 * G
+
+        .quad   0xb294634d82c9f57c
+        .quad   0x1fcbfde124934536
+        .quad   0x9e9c4db3418cdb5a
+        .quad   0x0040f3d9454419fc
+        .quad   0xf1bea8fb89ddbbad
+        .quad   0x3bcb2cbc61aeaecb
+        .quad   0x8f58a7bb1f9b8d9d
+        .quad   0x21547eda5112a686
+        .quad   0xdefde939fd5986d3
+        .quad   0xf4272c89510a380c
+        .quad   0xb72ba407bb3119b9
+        .quad   0x63550a334a254df4
+
+        // 2^232 * 5 * G
+
+        .quad   0x6507d6edb569cf37
+        .quad   0x178429b00ca52ee1
+        .quad   0xea7c0090eb6bd65d
+        .quad   0x3eea62c7daf78f51
+        .quad   0x9bba584572547b49
+        .quad   0xf305c6fae2c408e0
+        .quad   0x60e8fa69c734f18d
+        .quad   0x39a92bafaa7d767a
+        .quad   0x9d24c713e693274e
+        .quad   0x5f63857768dbd375
+        .quad   0x70525560eb8ab39a
+        .quad   0x68436a0665c9c4cd
+
+        // 2^232 * 6 * G
+
+        .quad   0xbc0235e8202f3f27
+        .quad   0xc75c00e264f975b0
+        .quad   0x91a4e9d5a38c2416
+        .quad   0x17b6e7f68ab789f9
+        .quad   0x1e56d317e820107c
+        .quad   0xc5266844840ae965
+        .quad   0xc1e0a1c6320ffc7a
+        .quad   0x5373669c91611472
+        .quad   0x5d2814ab9a0e5257
+        .quad   0x908f2084c9cab3fc
+        .quad   0xafcaf5885b2d1eca
+        .quad   0x1cb4b5a678f87d11
+
+        // 2^232 * 7 * G
+
+        .quad   0xb664c06b394afc6c
+        .quad   0x0c88de2498da5fb1
+        .quad   0x4f8d03164bcad834
+        .quad   0x330bca78de7434a2
+        .quad   0x6b74aa62a2a007e7
+        .quad   0xf311e0b0f071c7b1
+        .quad   0x5707e438000be223
+        .quad   0x2dc0fd2d82ef6eac
+        .quad   0x982eff841119744e
+        .quad   0xf9695e962b074724
+        .quad   0xc58ac14fbfc953fb
+        .quad   0x3c31be1b369f1cf5
+
+        // 2^232 * 8 * G
+
+        .quad   0xb0f4864d08948aee
+        .quad   0x07dc19ee91ba1c6f
+        .quad   0x7975cdaea6aca158
+        .quad   0x330b61134262d4bb
+        .quad   0xc168bc93f9cb4272
+        .quad   0xaeb8711fc7cedb98
+        .quad   0x7f0e52aa34ac8d7a
+        .quad   0x41cec1097e7d55bb
+        .quad   0xf79619d7a26d808a
+        .quad   0xbb1fd49e1d9e156d
+        .quad   0x73d7c36cdba1df27
+        .quad   0x26b44cd91f28777d
+
+        // 2^236 * 1 * G
+
+        .quad   0x300a9035393aa6d8
+        .quad   0x2b501131a12bb1cd
+        .quad   0x7b1ff677f093c222
+        .quad   0x4309c1f8cab82bad
+        .quad   0xaf44842db0285f37
+        .quad   0x8753189047efc8df
+        .quad   0x9574e091f820979a
+        .quad   0x0e378d6069615579
+        .quad   0xd9fa917183075a55
+        .quad   0x4bdb5ad26b009fdc
+        .quad   0x7829ad2cd63def0e
+        .quad   0x078fc54975fd3877
+
+        // 2^236 * 2 * G
+
+        .quad   0x87dfbd1428878f2d
+        .quad   0x134636dd1e9421a1
+        .quad   0x4f17c951257341a3
+        .quad   0x5df98d4bad296cb8
+        .quad   0xe2004b5bb833a98a
+        .quad   0x44775dec2d4c3330
+        .quad   0x3aa244067eace913
+        .quad   0x272630e3d58e00a9
+        .quad   0xf3678fd0ecc90b54
+        .quad   0xf001459b12043599
+        .quad   0x26725fbc3758b89b
+        .quad   0x4325e4aa73a719ae
+
+        // 2^236 * 3 * G
+
+        .quad   0x657dc6ef433c3493
+        .quad   0x65375e9f80dbf8c3
+        .quad   0x47fd2d465b372dae
+        .quad   0x4966ab79796e7947
+        .quad   0xed24629acf69f59d
+        .quad   0x2a4a1ccedd5abbf4
+        .quad   0x3535ca1f56b2d67b
+        .quad   0x5d8c68d043b1b42d
+        .quad   0xee332d4de3b42b0a
+        .quad   0xd84e5a2b16a4601c
+        .quad   0x78243877078ba3e4
+        .quad   0x77ed1eb4184ee437
+
+        // 2^236 * 4 * G
+
+        .quad   0xbfd4e13f201839a0
+        .quad   0xaeefffe23e3df161
+        .quad   0xb65b04f06b5d1fe3
+        .quad   0x52e085fb2b62fbc0
+        .quad   0x185d43f89e92ed1a
+        .quad   0xb04a1eeafe4719c6
+        .quad   0x499fbe88a6f03f4f
+        .quad   0x5d8b0d2f3c859bdd
+        .quad   0x124079eaa54cf2ba
+        .quad   0xd72465eb001b26e7
+        .quad   0x6843bcfdc97af7fd
+        .quad   0x0524b42b55eacd02
+
+        // 2^236 * 5 * G
+
+        .quad   0xfd0d5dbee45447b0
+        .quad   0x6cec351a092005ee
+        .quad   0x99a47844567579cb
+        .quad   0x59d242a216e7fa45
+        .quad   0xbc18dcad9b829eac
+        .quad   0x23ae7d28b5f579d0
+        .quad   0xc346122a69384233
+        .quad   0x1a6110b2e7d4ac89
+        .quad   0x4f833f6ae66997ac
+        .quad   0x6849762a361839a4
+        .quad   0x6985dec1970ab525
+        .quad   0x53045e89dcb1f546
+
+        // 2^236 * 6 * G
+
+        .quad   0xcb8bb346d75353db
+        .quad   0xfcfcb24bae511e22
+        .quad   0xcba48d40d50ae6ef
+        .quad   0x26e3bae5f4f7cb5d
+        .quad   0x84da3cde8d45fe12
+        .quad   0xbd42c218e444e2d2
+        .quad   0xa85196781f7e3598
+        .quad   0x7642c93f5616e2b2
+        .quad   0x2323daa74595f8e4
+        .quad   0xde688c8b857abeb4
+        .quad   0x3fc48e961c59326e
+        .quad   0x0b2e73ca15c9b8ba
+
+        // 2^236 * 7 * G
+
+        .quad   0xd6bb4428c17f5026
+        .quad   0x9eb27223fb5a9ca7
+        .quad   0xe37ba5031919c644
+        .quad   0x21ce380db59a6602
+        .quad   0x0e3fbfaf79c03a55
+        .quad   0x3077af054cbb5acf
+        .quad   0xd5c55245db3de39f
+        .quad   0x015e68c1476a4af7
+        .quad   0xc1d5285220066a38
+        .quad   0x95603e523570aef3
+        .quad   0x832659a7226b8a4d
+        .quad   0x5dd689091f8eedc9
+
+        // 2^236 * 8 * G
+
+        .quad   0xcbac84debfd3c856
+        .quad   0x1624c348b35ff244
+        .quad   0xb7f88dca5d9cad07
+        .quad   0x3b0e574da2c2ebe8
+        .quad   0x1d022591a5313084
+        .quad   0xca2d4aaed6270872
+        .quad   0x86a12b852f0bfd20
+        .quad   0x56e6c439ad7da748
+        .quad   0xc704ff4942bdbae6
+        .quad   0x5e21ade2b2de1f79
+        .quad   0xe95db3f35652fad8
+        .quad   0x0822b5378f08ebc1
+
+        // 2^240 * 1 * G
+
+        .quad   0x51f048478f387475
+        .quad   0xb25dbcf49cbecb3c
+        .quad   0x9aab1244d99f2055
+        .quad   0x2c709e6c1c10a5d6
+        .quad   0xe1b7f29362730383
+        .quad   0x4b5279ffebca8a2c
+        .quad   0xdafc778abfd41314
+        .quad   0x7deb10149c72610f
+        .quad   0xcb62af6a8766ee7a
+        .quad   0x66cbec045553cd0e
+        .quad   0x588001380f0be4b5
+        .quad   0x08e68e9ff62ce2ea
+
+        // 2^240 * 2 * G
+
+        .quad   0x34ad500a4bc130ad
+        .quad   0x8d38db493d0bd49c
+        .quad   0xa25c3d98500a89be
+        .quad   0x2f1f3f87eeba3b09
+        .quad   0x2f2d09d50ab8f2f9
+        .quad   0xacb9218dc55923df
+        .quad   0x4a8f342673766cb9
+        .quad   0x4cb13bd738f719f5
+        .quad   0xf7848c75e515b64a
+        .quad   0xa59501badb4a9038
+        .quad   0xc20d313f3f751b50
+        .quad   0x19a1e353c0ae2ee8
+
+        // 2^240 * 3 * G
+
+        .quad   0x7d1c7560bafa05c3
+        .quad   0xb3e1a0a0c6e55e61
+        .quad   0xe3529718c0d66473
+        .quad   0x41546b11c20c3486
+        .quad   0xb42172cdd596bdbd
+        .quad   0x93e0454398eefc40
+        .quad   0x9fb15347b44109b5
+        .quad   0x736bd3990266ae34
+        .quad   0x85532d509334b3b4
+        .quad   0x46fd114b60816573
+        .quad   0xcc5f5f30425c8375
+        .quad   0x412295a2b87fab5c
+
+        // 2^240 * 4 * G
+
+        .quad   0x19c99b88f57ed6e9
+        .quad   0x5393cb266df8c825
+        .quad   0x5cee3213b30ad273
+        .quad   0x14e153ebb52d2e34
+        .quad   0x2e655261e293eac6
+        .quad   0x845a92032133acdb
+        .quad   0x460975cb7900996b
+        .quad   0x0760bb8d195add80
+        .quad   0x413e1a17cde6818a
+        .quad   0x57156da9ed69a084
+        .quad   0x2cbf268f46caccb1
+        .quad   0x6b34be9bc33ac5f2
+
+        // 2^240 * 5 * G
+
+        .quad   0xf3df2f643a78c0b2
+        .quad   0x4c3e971ef22e027c
+        .quad   0xec7d1c5e49c1b5a3
+        .quad   0x2012c18f0922dd2d
+        .quad   0x11fc69656571f2d3
+        .quad   0xc6c9e845530e737a
+        .quad   0xe33ae7a2d4fe5035
+        .quad   0x01b9c7b62e6dd30b
+        .quad   0x880b55e55ac89d29
+        .quad   0x1483241f45a0a763
+        .quad   0x3d36efdfc2e76c1f
+        .quad   0x08af5b784e4bade8
+
+        // 2^240 * 6 * G
+
+        .quad   0x283499dc881f2533
+        .quad   0x9d0525da779323b6
+        .quad   0x897addfb673441f4
+        .quad   0x32b79d71163a168d
+        .quad   0xe27314d289cc2c4b
+        .quad   0x4be4bd11a287178d
+        .quad   0x18d528d6fa3364ce
+        .quad   0x6423c1d5afd9826e
+        .quad   0xcc85f8d9edfcb36a
+        .quad   0x22bcc28f3746e5f9
+        .quad   0xe49de338f9e5d3cd
+        .quad   0x480a5efbc13e2dcc
+
+        // 2^240 * 7 * G
+
+        .quad   0x0b51e70b01622071
+        .quad   0x06b505cf8b1dafc5
+        .quad   0x2c6bb061ef5aabcd
+        .quad   0x47aa27600cb7bf31
+        .quad   0xb6614ce442ce221f
+        .quad   0x6e199dcc4c053928
+        .quad   0x663fb4a4dc1cbe03
+        .quad   0x24b31d47691c8e06
+        .quad   0x2a541eedc015f8c3
+        .quad   0x11a4fe7e7c693f7c
+        .quad   0xf0af66134ea278d6
+        .quad   0x545b585d14dda094
+
+        // 2^240 * 8 * G
+
+        .quad   0x67bf275ea0d43a0f
+        .quad   0xade68e34089beebe
+        .quad   0x4289134cd479e72e
+        .quad   0x0f62f9c332ba5454
+        .quad   0x6204e4d0e3b321e1
+        .quad   0x3baa637a28ff1e95
+        .quad   0x0b0ccffd5b99bd9e
+        .quad   0x4d22dc3e64c8d071
+        .quad   0xfcb46589d63b5f39
+        .quad   0x5cae6a3f57cbcf61
+        .quad   0xfebac2d2953afa05
+        .quad   0x1c0fa01a36371436
+
+        // 2^244 * 1 * G
+
+        .quad   0xe7547449bc7cd692
+        .quad   0x0f9abeaae6f73ddf
+        .quad   0x4af01ca700837e29
+        .quad   0x63ab1b5d3f1bc183
+        .quad   0xc11ee5e854c53fae
+        .quad   0x6a0b06c12b4f3ff4
+        .quad   0x33540f80e0b67a72
+        .quad   0x15f18fc3cd07e3ef
+        .quad   0x32750763b028f48c
+        .quad   0x06020740556a065f
+        .quad   0xd53bd812c3495b58
+        .quad   0x08706c9b865f508d
+
+        // 2^244 * 2 * G
+
+        .quad   0xf37ca2ab3d343dff
+        .quad   0x1a8c6a2d80abc617
+        .quad   0x8e49e035d4ccffca
+        .quad   0x48b46beebaa1d1b9
+        .quad   0xcc991b4138b41246
+        .quad   0x243b9c526f9ac26b
+        .quad   0xb9ef494db7cbabbd
+        .quad   0x5fba433dd082ed00
+        .quad   0x9c49e355c9941ad0
+        .quad   0xb9734ade74498f84
+        .quad   0x41c3fed066663e5c
+        .quad   0x0ecfedf8e8e710b3
+
+        // 2^244 * 3 * G
+
+        .quad   0x76430f9f9cd470d9
+        .quad   0xb62acc9ba42f6008
+        .quad   0x1898297c59adad5e
+        .quad   0x7789dd2db78c5080
+        .quad   0x744f7463e9403762
+        .quad   0xf79a8dee8dfcc9c9
+        .quad   0x163a649655e4cde3
+        .quad   0x3b61788db284f435
+        .quad   0xb22228190d6ef6b2
+        .quad   0xa94a66b246ce4bfa
+        .quad   0x46c1a77a4f0b6cc7
+        .quad   0x4236ccffeb7338cf
+
+        // 2^244 * 4 * G
+
+        .quad   0x8497404d0d55e274
+        .quad   0x6c6663d9c4ad2b53
+        .quad   0xec2fb0d9ada95734
+        .quad   0x2617e120cdb8f73c
+        .quad   0x3bd82dbfda777df6
+        .quad   0x71b177cc0b98369e
+        .quad   0x1d0e8463850c3699
+        .quad   0x5a71945b48e2d1f1
+        .quad   0x6f203dd5405b4b42
+        .quad   0x327ec60410b24509
+        .quad   0x9c347230ac2a8846
+        .quad   0x77de29fc11ffeb6a
+
+        // 2^244 * 5 * G
+
+        .quad   0xb0ac57c983b778a8
+        .quad   0x53cdcca9d7fe912c
+        .quad   0x61c2b854ff1f59dc
+        .quad   0x3a1a2cf0f0de7dac
+        .quad   0x835e138fecced2ca
+        .quad   0x8c9eaf13ea963b9a
+        .quad   0xc95fbfc0b2160ea6
+        .quad   0x575e66f3ad877892
+        .quad   0x99803a27c88fcb3a
+        .quad   0x345a6789275ec0b0
+        .quad   0x459789d0ff6c2be5
+        .quad   0x62f882651e70a8b2
+
+        // 2^244 * 6 * G
+
+        .quad   0x085ae2c759ff1be4
+        .quad   0x149145c93b0e40b7
+        .quad   0xc467e7fa7ff27379
+        .quad   0x4eeecf0ad5c73a95
+        .quad   0x6d822986698a19e0
+        .quad   0xdc9821e174d78a71
+        .quad   0x41a85f31f6cb1f47
+        .quad   0x352721c2bcda9c51
+        .quad   0x48329952213fc985
+        .quad   0x1087cf0d368a1746
+        .quad   0x8e5261b166c15aa5
+        .quad   0x2d5b2d842ed24c21
+
+        // 2^244 * 7 * G
+
+        .quad   0x02cfebd9ebd3ded1
+        .quad   0xd45b217739021974
+        .quad   0x7576f813fe30a1b7
+        .quad   0x5691b6f9a34ef6c2
+        .quad   0x5eb7d13d196ac533
+        .quad   0x377234ecdb80be2b
+        .quad   0xe144cffc7cf5ae24
+        .quad   0x5226bcf9c441acec
+        .quad   0x79ee6c7223e5b547
+        .quad   0x6f5f50768330d679
+        .quad   0xed73e1e96d8adce9
+        .quad   0x27c3da1e1d8ccc03
+
+        // 2^244 * 8 * G
+
+        .quad   0x7eb9efb23fe24c74
+        .quad   0x3e50f49f1651be01
+        .quad   0x3ea732dc21858dea
+        .quad   0x17377bd75bb810f9
+        .quad   0x28302e71630ef9f6
+        .quad   0xc2d4a2032b64cee0
+        .quad   0x090820304b6292be
+        .quad   0x5fca747aa82adf18
+        .quad   0x232a03c35c258ea5
+        .quad   0x86f23a2c6bcb0cf1
+        .quad   0x3dad8d0d2e442166
+        .quad   0x04a8933cab76862b
+
+        // 2^248 * 1 * G
+
+        .quad   0xd2c604b622943dff
+        .quad   0xbc8cbece44cfb3a0
+        .quad   0x5d254ff397808678
+        .quad   0x0fa3614f3b1ca6bf
+        .quad   0x69082b0e8c936a50
+        .quad   0xf9c9a035c1dac5b6
+        .quad   0x6fb73e54c4dfb634
+        .quad   0x4005419b1d2bc140
+        .quad   0xa003febdb9be82f0
+        .quad   0x2089c1af3a44ac90
+        .quad   0xf8499f911954fa8e
+        .quad   0x1fba218aef40ab42
+
+        // 2^248 * 2 * G
+
+        .quad   0xab549448fac8f53e
+        .quad   0x81f6e89a7ba63741
+        .quad   0x74fd6c7d6c2b5e01
+        .quad   0x392e3acaa8c86e42
+        .quad   0x4f3e57043e7b0194
+        .quad   0xa81d3eee08daaf7f
+        .quad   0xc839c6ab99dcdef1
+        .quad   0x6c535d13ff7761d5
+        .quad   0x4cbd34e93e8a35af
+        .quad   0x2e0781445887e816
+        .quad   0x19319c76f29ab0ab
+        .quad   0x25e17fe4d50ac13b
+
+        // 2^248 * 3 * G
+
+        .quad   0x0a289bd71e04f676
+        .quad   0x208e1c52d6420f95
+        .quad   0x5186d8b034691fab
+        .quad   0x255751442a9fb351
+        .quad   0x915f7ff576f121a7
+        .quad   0xc34a32272fcd87e3
+        .quad   0xccba2fde4d1be526
+        .quad   0x6bba828f8969899b
+        .quad   0xe2d1bc6690fe3901
+        .quad   0x4cb54a18a0997ad5
+        .quad   0x971d6914af8460d4
+        .quad   0x559d504f7f6b7be4
+
+        // 2^248 * 4 * G
+
+        .quad   0xa7738378b3eb54d5
+        .quad   0x1d69d366a5553c7c
+        .quad   0x0a26cf62f92800ba
+        .quad   0x01ab12d5807e3217
+        .quad   0x9c4891e7f6d266fd
+        .quad   0x0744a19b0307781b
+        .quad   0x88388f1d6061e23b
+        .quad   0x123ea6a3354bd50e
+        .quad   0x118d189041e32d96
+        .quad   0xb9ede3c2d8315848
+        .quad   0x1eab4271d83245d9
+        .quad   0x4a3961e2c918a154
+
+        // 2^248 * 5 * G
+
+        .quad   0x71dc3be0f8e6bba0
+        .quad   0xd6cef8347effe30a
+        .quad   0xa992425fe13a476a
+        .quad   0x2cd6bce3fb1db763
+        .quad   0x0327d644f3233f1e
+        .quad   0x499a260e34fcf016
+        .quad   0x83b5a716f2dab979
+        .quad   0x68aceead9bd4111f
+        .quad   0x38b4c90ef3d7c210
+        .quad   0x308e6e24b7ad040c
+        .quad   0x3860d9f1b7e73e23
+        .quad   0x595760d5b508f597
+
+        // 2^248 * 6 * G
+
+        .quad   0x6129bfe104aa6397
+        .quad   0x8f960008a4a7fccb
+        .quad   0x3f8bc0897d909458
+        .quad   0x709fa43edcb291a9
+        .quad   0x882acbebfd022790
+        .quad   0x89af3305c4115760
+        .quad   0x65f492e37d3473f4
+        .quad   0x2cb2c5df54515a2b
+        .quad   0xeb0a5d8c63fd2aca
+        .quad   0xd22bc1662e694eff
+        .quad   0x2723f36ef8cbb03a
+        .quad   0x70f029ecf0c8131f
+
+        // 2^248 * 7 * G
+
+        .quad   0x461307b32eed3e33
+        .quad   0xae042f33a45581e7
+        .quad   0xc94449d3195f0366
+        .quad   0x0b7d5d8a6c314858
+        .quad   0x2a6aafaa5e10b0b9
+        .quad   0x78f0a370ef041aa9
+        .quad   0x773efb77aa3ad61f
+        .quad   0x44eca5a2a74bd9e1
+        .quad   0x25d448327b95d543
+        .quad   0x70d38300a3340f1d
+        .quad   0xde1c531c60e1c52b
+        .quad   0x272224512c7de9e4
+
+        // 2^248 * 8 * G
+
+        .quad   0x1abc92af49c5342e
+        .quad   0xffeed811b2e6fad0
+        .quad   0xefa28c8dfcc84e29
+        .quad   0x11b5df18a44cc543
+        .quad   0xbf7bbb8a42a975fc
+        .quad   0x8c5c397796ada358
+        .quad   0xe27fc76fcdedaa48
+        .quad   0x19735fd7f6bc20a6
+        .quad   0xe3ab90d042c84266
+        .quad   0xeb848e0f7f19547e
+        .quad   0x2503a1d065a497b9
+        .quad   0x0fef911191df895f
diff --git a/cbits/s2n/x86_att/edwards25519_scalarmulbase_alt.S b/cbits/s2n/x86_att/edwards25519_scalarmulbase_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/edwards25519_scalarmulbase_alt.S
@@ -0,0 +1,10002 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Scalar multiplication for the edwards25519 standard basepoint
+// Input scalar[4]; output res[8]
+//
+// extern void edwards25519_scalarmulbase_alt
+//   (uint64_t res[static 8],const uint64_t scalar[static 4]);
+//
+// Given a scalar n, returns point (X,Y) = n * B where B = (...,4/5) is
+// the standard basepoint for the edwards25519 (Ed25519) curve.
+//
+// Standard x86-64 ABI: RDI = res, RSI = scalar
+// Microsoft x64 ABI:   RCX = res, RDX = scalar
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(edwards25519_scalarmulbase_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(edwards25519_scalarmulbase_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(edwards25519_scalarmulbase_alt)
+
+        .text
+        .balign 32
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for result and temporaries on stack with some aliasing.
+// The result "resx" assumes the "res" pointer has been preloaded into %rbp.
+
+#define resx (0*NUMSIZE)(%rbp)
+#define resy (1*NUMSIZE)(%rbp)
+
+#define scalar (0*NUMSIZE)(%rsp)
+
+#define tabent (1*NUMSIZE)(%rsp)
+#define ymx_2 (1*NUMSIZE)(%rsp)
+#define xpy_2 (2*NUMSIZE)(%rsp)
+#define kxy_2 (3*NUMSIZE)(%rsp)
+
+#define t0 (4*NUMSIZE)(%rsp)
+#define t1 (5*NUMSIZE)(%rsp)
+#define t2 (6*NUMSIZE)(%rsp)
+#define t3 (7*NUMSIZE)(%rsp)
+#define t4 (8*NUMSIZE)(%rsp)
+#define t5 (9*NUMSIZE)(%rsp)
+
+#define acc (10*NUMSIZE)(%rsp)
+#define x_1 (10*NUMSIZE)(%rsp)
+#define y_1 (11*NUMSIZE)(%rsp)
+#define z_1 (12*NUMSIZE)(%rsp)
+#define w_1 (13*NUMSIZE)(%rsp)
+#define x_3 (10*NUMSIZE)(%rsp)
+#define y_3 (11*NUMSIZE)(%rsp)
+#define z_3 (12*NUMSIZE)(%rsp)
+#define w_3 (13*NUMSIZE)(%rsp)
+
+// Stable homes for the input result pointer, and other variables
+
+#define res  14*NUMSIZE(%rsp)
+
+#define i  14*NUMSIZE+8(%rsp)
+
+#define bias  14*NUMSIZE+16(%rsp)
+
+#define bf  14*NUMSIZE+24(%rsp)
+#define ix  14*NUMSIZE+24(%rsp)
+
+#define tab  15*NUMSIZE(%rsp)
+
+// Total size to reserve on the stack
+
+#define NSPACE 488
+
+// Syntactic variants to make x86_att version simpler to generate
+
+#define SCALAR 0
+#define TABENT (1*NUMSIZE)
+#define ACC (10*NUMSIZE)
+#define X3 (10*NUMSIZE)
+#define Z3 (12*NUMSIZE)
+#define W3 (13*NUMSIZE)
+
+// Macro wrapping up the basic field multiplication, only trivially
+// different from a pure function call to bignum_mul_p25519_alt.
+
+#define mul_p25519(P0,P1,P2)                    \
+        movq    P1, %rax ;                      \
+        mulq     P2;                 \
+        movq    %rax, %r8 ;                         \
+        movq    %rdx, %r9 ;                         \
+        xorq    %r10, %r10 ;                        \
+        xorq    %r11, %r11 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x8+P2;             \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     P2;                 \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        adcq    $0x0, %r11 ;                        \
+        xorq    %r12, %r12 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x10+P2;            \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    %r12, %r12 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x8+P2;             \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    $0x0, %r12 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     P2;                 \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    $0x0, %r12 ;                        \
+        xorq    %r13, %r13 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x18+P2;            \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    %r13, %r13 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x10+P2;            \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x8+P2;             \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     P2;                 \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        xorq    %r14, %r14 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x18+P2;            \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    %r14, %r14 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x10+P2;            \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    $0x0, %r14 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x8+P2;             \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    $0x0, %r14 ;                        \
+        xorq    %r15, %r15 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x18+P2;            \
+        addq    %rax, %r13 ;                        \
+        adcq    %rdx, %r14 ;                        \
+        adcq    %r15, %r15 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x10+P2;            \
+        addq    %rax, %r13 ;                        \
+        adcq    %rdx, %r14 ;                        \
+        adcq    $0x0, %r15 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x18+P2;            \
+        addq    %rax, %r14 ;                        \
+        adcq    %rdx, %r15 ;                        \
+        movl    $0x26, %esi ;                       \
+        movq    %r12, %rax ;                        \
+        mulq    %rsi;                            \
+        addq    %rax, %r8 ;                         \
+        adcq    %rdx, %r9 ;                         \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r13, %rax ;                        \
+        mulq    %rsi;                            \
+        subq    %rcx, %rdx ;                        \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r14, %rax ;                        \
+        mulq    %rsi;                            \
+        subq    %rcx, %rdx ;                        \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r15, %rax ;                        \
+        mulq    %rsi;                            \
+        subq    %rcx, %rdx ;                        \
+        xorq    %rcx, %rcx ;                        \
+        addq    %rax, %r11 ;                        \
+        movq    %rdx, %r12 ;                        \
+        adcq    %rcx, %r12 ;                        \
+        shldq   $0x1, %r11, %r12 ;                    \
+        leaq    0x1(%r12), %rax ;                  \
+        movl    $0x13, %esi ;                       \
+        bts     $63, %r11 ;                         \
+        imulq   %rsi, %rax ;                        \
+        addq    %rax, %r8 ;                         \
+        adcq    %rcx, %r9 ;                         \
+        adcq    %rcx, %r10 ;                        \
+        adcq    %rcx, %r11 ;                        \
+        sbbq    %rax, %rax ;                        \
+        notq    %rax;                            \
+        andq    %rsi, %rax ;                        \
+        subq    %rax, %r8 ;                         \
+        sbbq    %rcx, %r9 ;                         \
+        sbbq    %rcx, %r10 ;                        \
+        sbbq    %rcx, %r11 ;                        \
+        btr     $63, %r11 ;                         \
+        movq    %r8, P0 ;                        \
+        movq    %r9, 0x8+P0 ;                    \
+        movq    %r10, 0x10+P0 ;                  \
+        movq    %r11, 0x18+P0
+
+// A version of multiplication that only guarantees output < 2 * p_25519.
+// This basically skips the +1 and final correction in quotient estimation.
+
+#define mul_4(P0,P1,P2)                         \
+        movq    P1, %rax ;                      \
+        mulq     P2;                 \
+        movq    %rax, %r8 ;                         \
+        movq    %rdx, %r9 ;                         \
+        xorq    %r10, %r10 ;                        \
+        xorq    %r11, %r11 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x8+P2;             \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     P2;                 \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        adcq    $0x0, %r11 ;                        \
+        xorq    %r12, %r12 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x10+P2;            \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    %r12, %r12 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x8+P2;             \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    $0x0, %r12 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     P2;                 \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        adcq    $0x0, %r12 ;                        \
+        xorq    %r13, %r13 ;                        \
+        movq    P1, %rax ;                      \
+        mulq     0x18+P2;            \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    %r13, %r13 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x10+P2;            \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x8+P2;             \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     P2;                 \
+        addq    %rax, %r11 ;                        \
+        adcq    %rdx, %r12 ;                        \
+        adcq    $0x0, %r13 ;                        \
+        xorq    %r14, %r14 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq     0x18+P2;            \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    %r14, %r14 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x10+P2;            \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    $0x0, %r14 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x8+P2;             \
+        addq    %rax, %r12 ;                        \
+        adcq    %rdx, %r13 ;                        \
+        adcq    $0x0, %r14 ;                        \
+        xorq    %r15, %r15 ;                        \
+        movq    0x10+P1, %rax ;                 \
+        mulq     0x18+P2;            \
+        addq    %rax, %r13 ;                        \
+        adcq    %rdx, %r14 ;                        \
+        adcq    %r15, %r15 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x10+P2;            \
+        addq    %rax, %r13 ;                        \
+        adcq    %rdx, %r14 ;                        \
+        adcq    $0x0, %r15 ;                        \
+        movq    0x18+P1, %rax ;                 \
+        mulq     0x18+P2;            \
+        addq    %rax, %r14 ;                        \
+        adcq    %rdx, %r15 ;                        \
+        movl    $0x26, %ebx ;                       \
+        movq    %r12, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r8 ;                         \
+        adcq    %rdx, %r9 ;                         \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r13, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                        \
+        addq    %rax, %r9 ;                         \
+        adcq    %rdx, %r10 ;                        \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r14, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                        \
+        addq    %rax, %r10 ;                        \
+        adcq    %rdx, %r11 ;                        \
+        sbbq    %rcx, %rcx ;                        \
+        movq    %r15, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                        \
+        xorq    %rcx, %rcx ;                        \
+        addq    %rax, %r11 ;                        \
+        movq    %rdx, %r12 ;                        \
+        adcq    %rcx, %r12 ;                        \
+        shldq   $0x1, %r11, %r12 ;                    \
+        btr     $0x3f, %r11 ;                      \
+        movl    $0x13, %edx ;                      \
+        imulq   %r12, %rdx ;                       \
+        addq    %rdx, %r8 ;                        \
+        adcq    %rcx, %r9 ;                        \
+        adcq    %rcx, %r10 ;                       \
+        adcq    %rcx, %r11 ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 0x8+P0 ;                   \
+        movq    %r10, 0x10+P0 ;                 \
+        movq    %r11, 0x18+P0
+
+// Modular subtraction with double modulus 2 * p_25519 = 2^256 - 38
+
+#define sub_twice4(P0,P1,P2)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ebx, %ebx ;                       \
+        subq    P2, %r8 ;                       \
+        movq    8+P1, %r9 ;                     \
+        sbbq    8+P2, %r9 ;                     \
+        movl    $38, %ecx ;                        \
+        movq    16+P1, %r10 ;                   \
+        sbbq    16+P2, %r10 ;                   \
+        movq    24+P1, %rax ;                   \
+        sbbq    24+P2, %rax ;                   \
+        cmovncq %rbx, %rcx ;                       \
+        subq    %rcx, %r8 ;                        \
+        sbbq    %rbx, %r9 ;                        \
+        sbbq    %rbx, %r10 ;                       \
+        sbbq    %rbx, %rax ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 8+P0 ;                     \
+        movq    %r10, 16+P0 ;                   \
+        movq    %rax, 24+P0
+
+// Modular addition and doubling with double modulus 2 * p_25519 = 2^256 - 38.
+// This only ensures that the result fits in 4 digits, not that it is reduced
+// even w.r.t. double modulus. The result is always correct modulo provided
+// the sum of the inputs is < 2^256 + 2^256 - 38, so in particular provided
+// at least one of them is reduced double modulo.
+
+#define add_twice4(P0,P1,P2)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    P2, %r8 ;                       \
+        movq    0x8+P1, %r9 ;                   \
+        adcq    0x8+P2, %r9 ;                   \
+        movq    0x10+P1, %r10 ;                 \
+        adcq    0x10+P2, %r10 ;                 \
+        movq    0x18+P1, %r11 ;                 \
+        adcq    0x18+P2, %r11 ;                 \
+        movl    $38, %eax ;                        \
+        cmovncq %rcx, %rax ;                       \
+        addq    %rax, %r8 ;                        \
+        adcq    %rcx, %r9 ;                        \
+        adcq    %rcx, %r10 ;                       \
+        adcq    %rcx, %r11 ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 0x8+P0 ;                   \
+        movq    %r10, 0x10+P0 ;                 \
+        movq    %r11, 0x18+P0
+
+#define double_twice4(P0,P1)                    \
+        movq    P1, %r8 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    %r8, %r8 ;                         \
+        movq    0x8+P1, %r9 ;                   \
+        adcq    %r9, %r9 ;                         \
+        movq    0x10+P1, %r10 ;                 \
+        adcq    %r10, %r10 ;                       \
+        movq    0x18+P1, %r11 ;                 \
+        adcq    %r11, %r11 ;                       \
+        movl    $38, %eax ;                        \
+        cmovncq %rcx, %rax ;                       \
+        addq    %rax, %r8 ;                        \
+        adcq    %rcx, %r9 ;                        \
+        adcq    %rcx, %r10 ;                       \
+        adcq    %rcx, %r11 ;                       \
+        movq    %r8, P0 ;                       \
+        movq    %r9, 0x8+P0 ;                   \
+        movq    %r10, 0x10+P0 ;                 \
+        movq    %r11, 0x18+P0
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt):
+        CFI_START
+        _CET_ENDBR
+
+// In this case the Windows form literally makes a subroutine call.
+// This avoids hassle arising from keeping code and data together.
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        CFI_CALL(Ledwards25519_scalarmulbase_alt_standard)
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase_alt)
+
+S2N_BN_FUNCTION_TYPE_DIRECTIVE(Ledwards25519_scalarmulbase_alt_standard)
+
+Ledwards25519_scalarmulbase_alt_standard:
+        CFI_START
+#endif
+
+// Save registers, make room for temps, preserve input arguments.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+        CFI_DEC_RSP(NSPACE)
+
+// Move the output pointer to a stable place
+
+        movq    %rdi, res
+
+// Copy the input scalar x to its local variable while reducing it
+// modulo 2^252 + m where m = 27742317777372353535851937790883648493;
+// this is the order of the basepoint so this doesn't change the result.
+// First do q = floor(x/2^252) and x' = x - q * (2^252 + m), which gives
+// an initial result -15 * m <= x' < 2^252
+
+        movq    (%rsi), %r8
+        movq    8(%rsi), %r9
+        movq    16(%rsi), %r10
+        movq    24(%rsi), %r11
+
+        movq    %r11, %rcx
+        shrq    $60, %rcx
+
+        movq    $0x5812631a5cf5d3ed, %rax
+        mulq    %rcx
+        movq    %rax, %r12
+        movq    %rdx, %r13
+        movq    $0x14def9dea2f79cd6, %rax
+        mulq    %rcx
+        addq    %rax, %r13
+        adcq    $0, %rdx
+        shlq    $60, %rcx
+
+        subq    %r12, %r8
+        sbbq    %r13, %r9
+        sbbq    %rdx, %r10
+        sbbq    %rcx, %r11
+
+// If x' < 0 then just directly negate it; this makes sure the
+// reduced argument is strictly 0 <= x' < 2^252, but now we need
+// to record (done via bit 255 of the reduced scalar, which is
+// ignored in the main loop) when we negated so we can flip
+// the end result to compensate.
+
+        sbbq    %rax, %rax
+
+        xorq    %rax, %r8
+        xorq    %rax, %r9
+        xorq    %rax, %r10
+        xorq    %rax, %r11
+
+        negq    %rax
+        adcq    $0, %r8
+        adcq    $0, %r9
+        adcq    $0, %r10
+        adcq    $0, %r11
+
+        shlq    $63, %rax
+        orq     %rax, %r11
+
+// And before we store the scalar, test and reset bit 251 to
+// initialize the main loop just below.
+
+        movq    %r8, SCALAR(%rsp)
+        movq    %r9, SCALAR+8(%rsp)
+        movq    %r10, SCALAR+16(%rsp)
+        btr     $59, %r11
+        movq    %r11, SCALAR+24(%rsp)
+
+// The main part of the computation is in extended-projective coordinates
+// (X,Y,Z,T), representing an affine point on the edwards25519 curve
+// (x,y) via x = X/Z, y = Y/Z and x * y = T/Z (so X * Y = T * Z).
+// In comments B means the standard basepoint (x,4/5) =
+// (0x216....f25d51a,0x6666..666658).
+//
+// Initialize accumulator "acc" to either 0 or 2^251 * B depending on
+// bit 251 of the (reduced) scalar. That leaves bits 0..250 to handle.
+
+        leaq    S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant)(%rip), %r10
+        leaq    8*12(%r10), %r11
+
+        movq    (%r10), %rax
+        movq    (%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC(%rsp)
+
+        movq    8*1(%r10), %rax
+        movq    8*1(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+8(%rsp)
+
+        movq    8*2(%r10), %rax
+        movq    8*2(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+16(%rsp)
+
+        movq    8*3(%r10), %rax
+        movq    8*3(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+24(%rsp)
+
+        movq    8*4(%r10), %rax
+        movq    8*4(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+32(%rsp)
+
+        movq    8*5(%r10), %rax
+        movq    8*5(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+40(%rsp)
+
+        movq    8*6(%r10), %rax
+        movq    8*6(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+48(%rsp)
+
+        movq    8*7(%r10), %rax
+        movq    8*7(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+56(%rsp)
+
+        movl    $1, %eax
+        movq    %rax, ACC+64(%rsp)
+        movl    $0, %eax
+        movq    %rax, ACC+72(%rsp)
+        movq    %rax, ACC+80(%rsp)
+        movq    %rax, ACC+88(%rsp)
+
+        movq    8*8(%r10), %rax
+        movq    8*8(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+96(%rsp)
+
+        movq    8*9(%r10), %rax
+        movq    8*9(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+104(%rsp)
+
+        movq    8*10(%r10), %rax
+        movq    8*10(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+112(%rsp)
+
+        movq    8*11(%r10), %rax
+        movq    8*11(%r11), %rcx
+        cmovcq  %rcx, %rax
+        movq    %rax, ACC+120(%rsp)
+
+// The counter "i" tracks the bit position for which the scalar has
+// already been absorbed, starting at 0 and going up in chunks of 4.
+//
+// The pointer "tab" points at the current block of the table for
+// multiples (2^i * j) * B at the current bit position i; 1 <= j <= 8.
+//
+// The bias is always either 0 and 1 and needs to be added to the
+// partially processed scalar implicitly. This is used to absorb 4 bits
+// of scalar per iteration from 3-bit table indexing by exploiting
+// negation: (16 * h + l) * B = (16 * (h + 1) - (16 - l)) * B is used
+// when l >= 9. Note that we can't have any bias left over at the
+// end because we made sure bit 251 is clear in the reduced scalar.
+
+        movq    $0, i
+        leaq    8*24(%r10), %rax
+        movq    %rax, tab
+        movq    $0, bias
+
+// Start of the main loop, repeated 63 times for i = 4, 8, ..., 252
+
+Ledwards25519_scalarmulbase_alt_scalarloop:
+
+// Look at the next 4-bit field "bf", adding the previous bias as well.
+// Choose the table index "ix" as bf when bf <= 8 and 16 - bf for bf >= 9,
+// setting the bias to 1 for the next iteration in the latter case.
+
+        movq    i, %rax
+        movq    %rax, %rcx
+        shrq    $6, %rax
+        movq    (%rsp,%rax,8), %rax // Exploiting scalar = sp exactly
+        shrq    %cl, %rax
+        andq    $15, %rax
+        addq    bias, %rax
+        movq    %rax, bf
+
+        cmpq    $9, bf
+        sbbq    %rax, %rax
+        incq    %rax
+        movq    %rax, bias
+
+        movq    $16, %rdi
+        subq    bf, %rdi
+        cmpq    $0, bias
+        cmovzq  bf, %rdi
+        movq    %rdi, ix
+
+// Perform constant-time lookup in the table to get element number "ix".
+// The table entry for the affine point (x,y) is actually a triple
+// (y - x,x + y,2 * d * x * y) to precompute parts of the addition.
+// Note that "ix" can be 0, so we set up the appropriate identity first.
+
+        movl    $1, %eax
+        xorl    %ebx, %ebx
+        xorl    %ecx, %ecx
+        xorl    %edx, %edx
+        movl    $1, %r8d
+        xorl    %r9d, %r9d
+        xorl    %r10d, %r10d
+        xorl    %r11d, %r11d
+        xorl    %r12d, %r12d
+        xorl    %r13d, %r13d
+        xorl    %r14d, %r14d
+        xorl    %r15d, %r15d
+
+        movq    tab, %rbp
+
+        cmpq    $1, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $2, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $3, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $4, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $5, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $6, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $7, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+        addq    $96, %rbp
+
+        cmpq    $8, ix
+        movq    (%rbp), %rsi
+        cmovzq  %rsi, %rax
+        movq    8(%rbp), %rsi
+        cmovzq  %rsi, %rbx
+        movq    16(%rbp), %rsi
+        cmovzq  %rsi, %rcx
+        movq    24(%rbp), %rsi
+        cmovzq  %rsi, %rdx
+        movq    32(%rbp), %rsi
+        cmovzq  %rsi, %r8
+        movq    40(%rbp), %rsi
+        cmovzq  %rsi, %r9
+        movq    48(%rbp), %rsi
+        cmovzq  %rsi, %r10
+        movq    56(%rbp), %rsi
+        cmovzq  %rsi, %r11
+        movq    64(%rbp), %rsi
+        cmovzq  %rsi, %r12
+        movq    72(%rbp), %rsi
+        cmovzq  %rsi, %r13
+        movq    80(%rbp), %rsi
+        cmovzq  %rsi, %r14
+        movq    88(%rbp), %rsi
+        cmovzq  %rsi, %r15
+
+        addq    $96, %rbp
+        movq    %rbp, tab
+
+// We now have the triple from the table in registers as follows
+//
+//      [%rdx;%rcx;%rbx;%rax] = y - x
+//      [%r11;%r10;%r9;%r8] = x + y
+//      [%r15;%r14;%r13;%r12] = 2 * d * x * y
+//
+// In case bias = 1 we need to negate this. For Edwards curves
+// -(x,y) = (-x,y), i.e. we need to negate the x coordinate.
+// In this processed encoding, that amounts to swapping the
+// first two fields and negating the third.
+//
+// The optional negation here also pretends bias = 0 whenever
+// ix = 0 so that it doesn't need to handle the case of zero
+// inputs, since no non-trivial table entries are zero. Note
+// that in the zero case the whole negation is trivial, and
+// so indeed is the swapping.
+
+        cmpq    $0, bias
+
+        movq    %rax, %rsi
+        cmovnzq %r8, %rsi
+        cmovnzq %rax, %r8
+        movq    %rsi, TABENT(%rsp)
+        movq    %r8, TABENT+32(%rsp)
+
+        movq    %rbx, %rsi
+        cmovnzq %r9, %rsi
+        cmovnzq %rbx, %r9
+        movq    %rsi, TABENT+8(%rsp)
+        movq    %r9, TABENT+40(%rsp)
+
+        movq    %rcx, %rsi
+        cmovnzq %r10, %rsi
+        cmovnzq %rcx, %r10
+        movq    %rsi, TABENT+16(%rsp)
+        movq    %r10, TABENT+48(%rsp)
+
+        movq    %rdx, %rsi
+        cmovnzq %r11, %rsi
+        cmovnzq %rdx, %r11
+        movq    %rsi, TABENT+24(%rsp)
+        movq    %r11, TABENT+56(%rsp)
+
+        movq    $-19, %rax
+        movq    $-1, %rbx
+        movq    $-1, %rcx
+        movq    $0x7fffffffffffffff, %rdx
+        subq    %r12, %rax
+        sbbq    %r13, %rbx
+        sbbq    %r14, %rcx
+        sbbq    %r15, %rdx
+
+        movq    ix, %r8
+        movq    bias, %r9
+        testq   %r8, %r8
+        cmovzq  %r8, %r9
+        testq   %r9, %r9
+
+        cmovzq  %r12, %rax
+        cmovzq  %r13, %rbx
+        cmovzq  %r14, %rcx
+        cmovzq  %r15, %rdx
+        movq    %rax, TABENT+64(%rsp)
+        movq    %rbx, TABENT+72(%rsp)
+        movq    %rcx, TABENT+80(%rsp)
+        movq    %rdx, TABENT+88(%rsp)
+
+// Extended-projective and precomputed mixed addition.
+// This is effectively the same as calling the standalone
+// function edwards25519_pepadd(acc,acc,tabent), but we
+// only retain slightly weaker normalization < 2 * p_25519
+// throughout the inner loop, so the computation is
+// slightly different, and faster overall.
+
+        double_twice4(t0,z_1)
+        sub_twice4(t1,y_1,x_1)
+        add_twice4(t2,y_1,x_1)
+        mul_4(t3,w_1,kxy_2)
+        mul_4(t1,t1,ymx_2)
+        mul_4(t2,t2,xpy_2)
+        sub_twice4(t4,t0,t3)
+        add_twice4(t0,t0,t3)
+        sub_twice4(t5,t2,t1)
+        add_twice4(t1,t2,t1)
+        mul_4(z_3,t4,t0)
+        mul_4(x_3,t5,t4)
+        mul_4(y_3,t0,t1)
+        mul_4(w_3,t5,t1)
+
+// End of the main loop; move on by 4 bits.
+
+        addq    $4, i
+        cmpq    $252, i
+        jc      Ledwards25519_scalarmulbase_alt_scalarloop
+
+// Insert the optional negation of the projective X coordinate, and
+// so by extension the final affine x coordinate x = X/Z and thus
+// the point P = (x,y). We only know X < 2 * p_25519, so we do the
+// negation as 2 * p_25519 - X to keep it nonnegative. From this
+// point on we don't need any normalization of the coordinates
+// except for making sure that they fit in 4 digits.
+
+        movq    X3(%rsp), %r8
+        movq    X3+8(%rsp), %r9
+        movq    X3+16(%rsp), %r10
+        movq    X3+24(%rsp), %r11
+        movq    $0xffffffffffffffda, %r12
+        subq    %r8, %r12
+        movq    $0xffffffffffffffff, %r13
+        sbbq    %r9, %r13
+        movq    $0xffffffffffffffff, %r14
+        sbbq    %r10, %r14
+        movq    $0xffffffffffffffff, %r15
+        sbbq    %r11, %r15
+        movq    SCALAR+24(%rsp), %rax
+        btq     $63, %rax
+        cmovcq  %r12, %r8
+        cmovcq  %r13, %r9
+        cmovcq  %r14, %r10
+        cmovcq  %r15, %r11
+        movq    %r8, X3(%rsp)
+        movq    %r9, X3+8(%rsp)
+        movq    %r10, X3+16(%rsp)
+        movq    %r11, X3+24(%rsp)
+
+// Now we need to map out of the extended-projective representation
+// (X,Y,Z,W) back to the affine form (x,y) = (X/Z,Y/Z). This means
+// first calling the modular inverse to get w_3 = 1/z_3.
+
+        leaq    W3(%rsp), %rdi
+        leaq    Z3(%rsp), %rsi
+
+// Inline copy of bignum_inv_p25519, identical except for stripping out
+// the prologue and epilogue saving and restoring registers and making
+// and reclaiming room on the stack. For more details and explanations see
+// "x86/curve25519/bignum_inv_p25519.S". Note that the stack it uses for
+// its own temporaries is 208 bytes, so it has no effect on variables
+// that are needed in the rest of our computation here: res, x_3, y_3,
+// z_3 and w_3.
+
+        movq    %rdi, 0xc0(%rsp)
+        xorl    %eax, %eax
+        leaq    -0x13(%rax), %rcx
+        notq    %rax
+        movq    %rcx, (%rsp)
+        movq    %rax, 0x8(%rsp)
+        movq    %rax, 0x10(%rsp)
+        btr     $0x3f, %rax
+        movq    %rax, 0x18(%rsp)
+        movq    (%rsi), %rdx
+        movq    0x8(%rsi), %rcx
+        movq    0x10(%rsi), %r8
+        movq    0x18(%rsi), %r9
+        movl    $0x1, %eax
+        xorl    %r10d, %r10d
+        bts     $0x3f, %r9
+        adcq    %r10, %rax
+        imulq   $0x13, %rax, %rax
+        addq    %rax, %rdx
+        adcq    %r10, %rcx
+        adcq    %r10, %r8
+        adcq    %r10, %r9
+        movl    $0x13, %eax
+        cmovbq  %r10, %rax
+        subq    %rax, %rdx
+        sbbq    %r10, %rcx
+        sbbq    %r10, %r8
+        sbbq    %r10, %r9
+        btr     $0x3f, %r9
+        movq    %rdx, 0x20(%rsp)
+        movq    %rcx, 0x28(%rsp)
+        movq    %r8, 0x30(%rsp)
+        movq    %r9, 0x38(%rsp)
+        xorl    %eax, %eax
+        movq    %rax, 0x40(%rsp)
+        movq    %rax, 0x48(%rsp)
+        movq    %rax, 0x50(%rsp)
+        movq    %rax, 0x58(%rsp)
+        movabsq $0xa0f99e2375022099, %rax
+        movq    %rax, 0x60(%rsp)
+        movabsq $0xa8c68f3f1d132595, %rax
+        movq    %rax, 0x68(%rsp)
+        movabsq $0x6c6c893805ac5242, %rax
+        movq    %rax, 0x70(%rsp)
+        movabsq $0x276508b241770615, %rax
+        movq    %rax, 0x78(%rsp)
+        movq    $0xa,  0x90(%rsp)
+        movq    $0x1,  0x98(%rsp)
+        jmp     Ledwards25519_scalarmulbase_alt_midloop
+Ledwards25519_scalarmulbase_alt_inverseloop:
+        movq    %r8, %r9
+        sarq    $0x3f, %r9
+        xorq    %r9, %r8
+        subq    %r9, %r8
+        movq    %r10, %r11
+        sarq    $0x3f, %r11
+        xorq    %r11, %r10
+        subq    %r11, %r10
+        movq    %r12, %r13
+        sarq    $0x3f, %r13
+        xorq    %r13, %r12
+        subq    %r13, %r12
+        movq    %r14, %r15
+        sarq    $0x3f, %r15
+        xorq    %r15, %r14
+        subq    %r15, %r14
+        movq    %r8, %rax
+        andq    %r9, %rax
+        movq    %r10, %rdi
+        andq    %r11, %rdi
+        addq    %rax, %rdi
+        movq    %rdi, 0x80(%rsp)
+        movq    %r12, %rax
+        andq    %r13, %rax
+        movq    %r14, %rsi
+        andq    %r15, %rsi
+        addq    %rax, %rsi
+        movq    %rsi, 0x88(%rsp)
+        xorl    %ebx, %ebx
+        movq    (%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        movq    0x20(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        xorl    %ebp, %ebp
+        movq    (%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x20(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        xorl    %ecx, %ecx
+        movq    0x8(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x28(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        shrdq   $0x3b, %rbx, %rdi
+        movq    %rdi, (%rsp)
+        xorl    %edi, %edi
+        movq    0x8(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rbp
+        adcq    %rdx, %rdi
+        movq    0x28(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rdi
+        shrdq   $0x3b, %rbp, %rsi
+        movq    %rsi, 0x20(%rsp)
+        xorl    %esi, %esi
+        movq    0x10(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rsi
+        movq    0x30(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rdx, %rsi
+        shrdq   $0x3b, %rcx, %rbx
+        movq    %rbx, 0x8(%rsp)
+        xorl    %ebx, %ebx
+        movq    0x10(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        movq    0x30(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rdi
+        adcq    %rdx, %rbx
+        shrdq   $0x3b, %rdi, %rbp
+        movq    %rbp, 0x28(%rsp)
+        movq    0x18(%rsp), %rax
+        xorq    %r9, %rax
+        movq    %rax, %rbp
+        sarq    $0x3f, %rbp
+        andq    %r8, %rbp
+        negq    %rbp
+        mulq    %r8
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x38(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %rax, %rdx
+        sarq    $0x3f, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %rbp
+        mulq    %r10
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        shrdq   $0x3b, %rsi, %rcx
+        movq    %rcx, 0x10(%rsp)
+        shrdq   $0x3b, %rbp, %rsi
+        movq    0x18(%rsp), %rax
+        movq    %rsi, 0x18(%rsp)
+        xorq    %r13, %rax
+        movq    %rax, %rsi
+        sarq    $0x3f, %rsi
+        andq    %r12, %rsi
+        negq    %rsi
+        mulq    %r12
+        addq    %rax, %rbx
+        adcq    %rdx, %rsi
+        movq    0x38(%rsp), %rax
+        xorq    %r15, %rax
+        movq    %rax, %rdx
+        sarq    $0x3f, %rdx
+        andq    %r14, %rdx
+        subq    %rdx, %rsi
+        mulq    %r14
+        addq    %rax, %rbx
+        adcq    %rdx, %rsi
+        shrdq   $0x3b, %rbx, %rdi
+        movq    %rdi, 0x30(%rsp)
+        shrdq   $0x3b, %rsi, %rbx
+        movq    %rbx, 0x38(%rsp)
+        movq    0x80(%rsp), %rbx
+        movq    0x88(%rsp), %rbp
+        xorl    %ecx, %ecx
+        movq    0x40(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x60(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        xorl    %esi, %esi
+        movq    0x40(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rbx, 0x40(%rsp)
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    0x60(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    %rbp, 0x60(%rsp)
+        xorl    %ebx, %ebx
+        movq    0x48(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        movq    0x68(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        xorl    %ebp, %ebp
+        movq    0x48(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rcx, 0x48(%rsp)
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    0x68(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rdx, %rbp
+        movq    %rsi, 0x68(%rsp)
+        xorl    %ecx, %ecx
+        movq    0x50(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        movq    0x70(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %rbx
+        adcq    %rdx, %rcx
+        xorl    %esi, %esi
+        movq    0x50(%rsp), %rax
+        xorq    %r13, %rax
+        mulq    %r12
+        movq    %rbx, 0x50(%rsp)
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    0x70(%rsp), %rax
+        xorq    %r15, %rax
+        mulq    %r14
+        addq    %rax, %rbp
+        adcq    %rdx, %rsi
+        movq    %rbp, 0x70(%rsp)
+        movq    0x58(%rsp), %rax
+        xorq    %r9, %rax
+        movq    %r9, %rbx
+        andq    %r8, %rbx
+        negq    %rbx
+        mulq    %r8
+        addq    %rax, %rcx
+        adcq    %rdx, %rbx
+        movq    0x78(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %r11, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %rbx
+        mulq    %r10
+        addq    %rax, %rcx
+        adcq    %rbx, %rdx
+        movq    %rdx, %rbx
+        shldq   $0x1, %rcx, %rdx
+        sarq    $0x3f, %rbx
+        addq    %rbx, %rdx
+        movl    $0x13, %eax
+        imulq   %rdx
+        movq    0x40(%rsp), %r8
+        addq    %rax, %r8
+        movq    %r8, 0x40(%rsp)
+        movq    0x48(%rsp), %r8
+        adcq    %rdx, %r8
+        movq    %r8, 0x48(%rsp)
+        movq    0x50(%rsp), %r8
+        adcq    %rbx, %r8
+        movq    %r8, 0x50(%rsp)
+        adcq    %rbx, %rcx
+        shlq    $0x3f, %rax
+        addq    %rax, %rcx
+        movq    0x58(%rsp), %rax
+        movq    %rcx, 0x58(%rsp)
+        xorq    %r13, %rax
+        movq    %r13, %rcx
+        andq    %r12, %rcx
+        negq    %rcx
+        mulq    %r12
+        addq    %rax, %rsi
+        adcq    %rdx, %rcx
+        movq    0x78(%rsp), %rax
+        xorq    %r15, %rax
+        movq    %r15, %rdx
+        andq    %r14, %rdx
+        subq    %rdx, %rcx
+        mulq    %r14
+        addq    %rax, %rsi
+        adcq    %rcx, %rdx
+        movq    %rdx, %rcx
+        shldq   $0x1, %rsi, %rdx
+        sarq    $0x3f, %rcx
+        movl    $0x13, %eax
+        addq    %rcx, %rdx
+        imulq   %rdx
+        movq    0x60(%rsp), %r8
+        addq    %rax, %r8
+        movq    %r8, 0x60(%rsp)
+        movq    0x68(%rsp), %r8
+        adcq    %rdx, %r8
+        movq    %r8, 0x68(%rsp)
+        movq    0x70(%rsp), %r8
+        adcq    %rcx, %r8
+        movq    %r8, 0x70(%rsp)
+        adcq    %rcx, %rsi
+        shlq    $0x3f, %rax
+        addq    %rax, %rsi
+        movq    %rsi, 0x78(%rsp)
+Ledwards25519_scalarmulbase_alt_midloop:
+        movq    0x98(%rsp), %rsi
+        movq    (%rsp), %rdx
+        movq    0x20(%rsp), %rcx
+        movq    %rdx, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    $0xfffffffffffffffe, %rax
+        xorl    %ebp, %ebp
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %rdx
+        leaq    (%rcx,%rax), %rdi
+        shlq    $0x16, %rdx
+        shlq    $0x16, %rdi
+        sarq    $0x2b, %rdx
+        sarq    $0x2b, %rdi
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %rbx
+        leaq    (%rcx,%rax), %rcx
+        sarq    $0x2a, %rbx
+        sarq    $0x2a, %rcx
+        movq    %rdx, 0xa0(%rsp)
+        movq    %rbx, 0xa8(%rsp)
+        movq    %rdi, 0xb0(%rsp)
+        movq    %rcx, 0xb8(%rsp)
+        movq    (%rsp), %r12
+        imulq   %r12, %rdi
+        imulq   %rdx, %r12
+        movq    0x20(%rsp), %r13
+        imulq   %r13, %rbx
+        imulq   %rcx, %r13
+        addq    %rbx, %r12
+        addq    %rdi, %r13
+        sarq    $0x14, %r12
+        sarq    $0x14, %r13
+        movq    %r12, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        movq    %r13, %rcx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    $0xfffffffffffffffe, %rax
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %r8
+        leaq    (%rcx,%rax), %r10
+        shlq    $0x16, %r8
+        shlq    $0x16, %r10
+        sarq    $0x2b, %r8
+        sarq    $0x2b, %r10
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %r15
+        leaq    (%rcx,%rax), %r11
+        sarq    $0x2a, %r15
+        sarq    $0x2a, %r11
+        movq    %r13, %rbx
+        movq    %r12, %rcx
+        imulq   %r8, %r12
+        imulq   %r15, %rbx
+        addq    %rbx, %r12
+        imulq   %r11, %r13
+        imulq   %r10, %rcx
+        addq    %rcx, %r13
+        sarq    $0x14, %r12
+        sarq    $0x14, %r13
+        movq    %r12, %rbx
+        andq    $0xfffff, %rbx
+        movabsq $0xfffffe0000000000, %rax
+        orq     %rax, %rbx
+        movq    %r13, %rcx
+        andq    $0xfffff, %rcx
+        movabsq $0xc000000000000000, %rax
+        orq     %rax, %rcx
+        movq    0xa0(%rsp), %rax
+        imulq   %r8, %rax
+        movq    0xb0(%rsp), %rdx
+        imulq   %r15, %rdx
+        imulq   0xa8(%rsp), %r8
+        imulq   0xb8(%rsp), %r15
+        addq    %r8, %r15
+        leaq    (%rax,%rdx), %r9
+        movq    0xa0(%rsp), %rax
+        imulq   %r10, %rax
+        movq    0xb0(%rsp), %rdx
+        imulq   %r11, %rdx
+        imulq   0xa8(%rsp), %r10
+        imulq   0xb8(%rsp), %r11
+        addq    %r10, %r11
+        leaq    (%rax,%rdx), %r13
+        movq    $0xfffffffffffffffe, %rax
+        movl    $0x2, %edx
+        movq    %rbx, %rdi
+        movq    %rax, %r8
+        testq   %rsi, %rsi
+        cmovs   %rbp, %r8
+        testq   $0x1, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        cmovs   %rbp, %r8
+        movq    %rbx, %rdi
+        testq   %rdx, %rcx
+        cmoveq  %rbp, %r8
+        cmoveq  %rbp, %rdi
+        sarq    $1, %rcx
+        xorq    %r8, %rdi
+        xorq    %r8, %rsi
+        btq     $0x3f, %r8
+        cmovbq  %rcx, %rbx
+        movq    %rax, %r8
+        subq    %rax, %rsi
+        leaq    (%rcx,%rdi), %rcx
+        sarq    $1, %rcx
+        movl    $0x100000, %eax
+        leaq    (%rbx,%rax), %r8
+        leaq    (%rcx,%rax), %r12
+        shlq    $0x15, %r8
+        shlq    $0x15, %r12
+        sarq    $0x2b, %r8
+        sarq    $0x2b, %r12
+        movabsq $0x20000100000, %rax
+        leaq    (%rbx,%rax), %r10
+        leaq    (%rcx,%rax), %r14
+        sarq    $0x2b, %r10
+        sarq    $0x2b, %r14
+        movq    %r9, %rax
+        imulq   %r8, %rax
+        movq    %r13, %rdx
+        imulq   %r10, %rdx
+        imulq   %r15, %r8
+        imulq   %r11, %r10
+        addq    %r8, %r10
+        leaq    (%rax,%rdx), %r8
+        movq    %r9, %rax
+        imulq   %r12, %rax
+        movq    %r13, %rdx
+        imulq   %r14, %rdx
+        imulq   %r15, %r12
+        imulq   %r11, %r14
+        addq    %r12, %r14
+        leaq    (%rax,%rdx), %r12
+        movq    %rsi, 0x98(%rsp)
+        decq     0x90(%rsp)
+        jne     Ledwards25519_scalarmulbase_alt_inverseloop
+        movq    (%rsp), %rax
+        movq    0x20(%rsp), %rcx
+        imulq   %r8, %rax
+        imulq   %r10, %rcx
+        addq    %rcx, %rax
+        sarq    $0x3f, %rax
+        movq    %r8, %r9
+        sarq    $0x3f, %r9
+        xorq    %r9, %r8
+        subq    %r9, %r8
+        xorq    %rax, %r9
+        movq    %r10, %r11
+        sarq    $0x3f, %r11
+        xorq    %r11, %r10
+        subq    %r11, %r10
+        xorq    %rax, %r11
+        movq    %r12, %r13
+        sarq    $0x3f, %r13
+        xorq    %r13, %r12
+        subq    %r13, %r12
+        xorq    %rax, %r13
+        movq    %r14, %r15
+        sarq    $0x3f, %r15
+        xorq    %r15, %r14
+        subq    %r15, %r14
+        xorq    %rax, %r15
+        movq    %r8, %rax
+        andq    %r9, %rax
+        movq    %r10, %r12
+        andq    %r11, %r12
+        addq    %rax, %r12
+        xorl    %r13d, %r13d
+        movq    0x40(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        movq    0x60(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        xorl    %r14d, %r14d
+        movq    0x48(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r13
+        adcq    %rdx, %r14
+        movq    0x68(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r13
+        adcq    %rdx, %r14
+        xorl    %r15d, %r15d
+        movq    0x50(%rsp), %rax
+        xorq    %r9, %rax
+        mulq    %r8
+        addq    %rax, %r14
+        adcq    %rdx, %r15
+        movq    0x70(%rsp), %rax
+        xorq    %r11, %rax
+        mulq    %r10
+        addq    %rax, %r14
+        adcq    %rdx, %r15
+        movq    0x58(%rsp), %rax
+        xorq    %r9, %rax
+        andq    %r8, %r9
+        negq    %r9
+        mulq    %r8
+        addq    %rax, %r15
+        adcq    %rdx, %r9
+        movq    0x78(%rsp), %rax
+        xorq    %r11, %rax
+        movq    %r11, %rdx
+        andq    %r10, %rdx
+        subq    %rdx, %r9
+        mulq    %r10
+        addq    %rax, %r15
+        adcq    %rdx, %r9
+        movq    %r9, %rax
+        shldq   $0x1, %r15, %rax
+        sarq    $0x3f, %r9
+        movl    $0x13, %ebx
+        leaq    0x1(%rax,%r9,1), %rax
+        imulq   %rbx
+        xorl    %ebp, %ebp
+        addq    %rax, %r12
+        adcq    %rdx, %r13
+        adcq    %r9, %r14
+        adcq    %r9, %r15
+        shlq    $0x3f, %rax
+        addq    %rax, %r15
+        cmovns  %rbp, %rbx
+        subq    %rbx, %r12
+        sbbq    %rbp, %r13
+        sbbq    %rbp, %r14
+        sbbq    %rbp, %r15
+        btr     $0x3f, %r15
+        movq    0xc0(%rsp), %rdi
+        movq    %r12, (%rdi)
+        movq    %r13, 0x8(%rdi)
+        movq    %r14, 0x10(%rdi)
+        movq    %r15, 0x18(%rdi)
+
+// The final result is x = X * inv(Z), y = Y * inv(Z).
+// These are the only operations in the whole computation that
+// fully reduce modulo p_25519 since now we want the canonical
+// answer as output.
+
+        movq    res, %rbp
+        mul_p25519(resx,x_3,w_3)
+        mul_p25519(resy,y_3,w_3)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+        CFI_RET
+
+#if WINDOWS_ABI
+S2N_BN_SIZE_DIRECTIVE(Ledwards25519_scalarmulbase_alt_standard)
+#else
+S2N_BN_SIZE_DIRECTIVE(edwards25519_scalarmulbase_alt)
+#endif
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
+
+// ****************************************************************************
+// The precomputed data (all read-only).
+// ****************************************************************************
+
+#if defined(__ELF__)
+.section .rodata
+.type S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant), %object
+.size S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant), 48576
+#elif defined(__APPLE__)
+.const_data
+#endif
+
+S2N_BN_SYMBOL(edwards25519_scalarmulbase_alt_constant):
+
+// 0 * B = 0 and 2^251 * B in extended-projective coordinates
+// but with Z = 1 assumed and hence left out, so they are (X,Y,T) only.
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x0000000000000001
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+        .quad   0x0000000000000000
+
+        .quad   0x525f946d7c7220e7
+        .quad   0x4636b0b2f1e35444
+        .quad   0x796e9d70e892ae0f
+        .quad   0x03dec05fa937adb1
+        .quad   0x6d1c271cc6375515
+        .quad   0x462588c4a4ca4f14
+        .quad   0x691129fee55afc39
+        .quad   0x15949f784d8472f5
+        .quad   0xbd89e510afad0049
+        .quad   0x4d1f08c073b9860e
+        .quad   0x07716e8b2d00af9d
+        .quad   0x70d685f68f859714
+
+// Precomputed table of multiples of generator for edwards25519
+// all in precomputed extended-projective (y-x,x+y,2*d*x*y) triples.
+
+        // 2^0 * 1 * G
+
+        .quad   0x9d103905d740913e
+        .quad   0xfd399f05d140beb3
+        .quad   0xa5c18434688f8a09
+        .quad   0x44fd2f9298f81267
+        .quad   0x2fbc93c6f58c3b85
+        .quad   0xcf932dc6fb8c0e19
+        .quad   0x270b4898643d42c2
+        .quad   0x07cf9d3a33d4ba65
+        .quad   0xabc91205877aaa68
+        .quad   0x26d9e823ccaac49e
+        .quad   0x5a1b7dcbdd43598c
+        .quad   0x6f117b689f0c65a8
+
+        // 2^0 * 2 * G
+
+        .quad   0x8a99a56042b4d5a8
+        .quad   0x8f2b810c4e60acf6
+        .quad   0xe09e236bb16e37aa
+        .quad   0x6bb595a669c92555
+        .quad   0x9224e7fc933c71d7
+        .quad   0x9f469d967a0ff5b5
+        .quad   0x5aa69a65e1d60702
+        .quad   0x590c063fa87d2e2e
+        .quad   0x43faa8b3a59b7a5f
+        .quad   0x36c16bdd5d9acf78
+        .quad   0x500fa0840b3d6a31
+        .quad   0x701af5b13ea50b73
+
+        // 2^0 * 3 * G
+
+        .quad   0x56611fe8a4fcd265
+        .quad   0x3bd353fde5c1ba7d
+        .quad   0x8131f31a214bd6bd
+        .quad   0x2ab91587555bda62
+        .quad   0xaf25b0a84cee9730
+        .quad   0x025a8430e8864b8a
+        .quad   0xc11b50029f016732
+        .quad   0x7a164e1b9a80f8f4
+        .quad   0x14ae933f0dd0d889
+        .quad   0x589423221c35da62
+        .quad   0xd170e5458cf2db4c
+        .quad   0x5a2826af12b9b4c6
+
+        // 2^0 * 4 * G
+
+        .quad   0x95fe050a056818bf
+        .quad   0x327e89715660faa9
+        .quad   0xc3e8e3cd06a05073
+        .quad   0x27933f4c7445a49a
+        .quad   0x287351b98efc099f
+        .quad   0x6765c6f47dfd2538
+        .quad   0xca348d3dfb0a9265
+        .quad   0x680e910321e58727
+        .quad   0x5a13fbe9c476ff09
+        .quad   0x6e9e39457b5cc172
+        .quad   0x5ddbdcf9102b4494
+        .quad   0x7f9d0cbf63553e2b
+
+        // 2^0 * 5 * G
+
+        .quad   0x7f9182c3a447d6ba
+        .quad   0xd50014d14b2729b7
+        .quad   0xe33cf11cb864a087
+        .quad   0x154a7e73eb1b55f3
+        .quad   0xa212bc4408a5bb33
+        .quad   0x8d5048c3c75eed02
+        .quad   0xdd1beb0c5abfec44
+        .quad   0x2945ccf146e206eb
+        .quad   0xbcbbdbf1812a8285
+        .quad   0x270e0807d0bdd1fc
+        .quad   0xb41b670b1bbda72d
+        .quad   0x43aabe696b3bb69a
+
+        // 2^0 * 6 * G
+
+        .quad   0x499806b67b7d8ca4
+        .quad   0x575be28427d22739
+        .quad   0xbb085ce7204553b9
+        .quad   0x38b64c41ae417884
+        .quad   0x3a0ceeeb77157131
+        .quad   0x9b27158900c8af88
+        .quad   0x8065b668da59a736
+        .quad   0x51e57bb6a2cc38bd
+        .quad   0x85ac326702ea4b71
+        .quad   0xbe70e00341a1bb01
+        .quad   0x53e4a24b083bc144
+        .quad   0x10b8e91a9f0d61e3
+
+        // 2^0 * 7 * G
+
+        .quad   0xba6f2c9aaa3221b1
+        .quad   0x6ca021533bba23a7
+        .quad   0x9dea764f92192c3a
+        .quad   0x1d6edd5d2e5317e0
+        .quad   0x6b1a5cd0944ea3bf
+        .quad   0x7470353ab39dc0d2
+        .quad   0x71b2528228542e49
+        .quad   0x461bea69283c927e
+        .quad   0xf1836dc801b8b3a2
+        .quad   0xb3035f47053ea49a
+        .quad   0x529c41ba5877adf3
+        .quad   0x7a9fbb1c6a0f90a7
+
+        // 2^0 * 8 * G
+
+        .quad   0xe2a75dedf39234d9
+        .quad   0x963d7680e1b558f9
+        .quad   0x2c2741ac6e3c23fb
+        .quad   0x3a9024a1320e01c3
+        .quad   0x59b7596604dd3e8f
+        .quad   0x6cb30377e288702c
+        .quad   0xb1339c665ed9c323
+        .quad   0x0915e76061bce52f
+        .quad   0xe7c1f5d9c9a2911a
+        .quad   0xb8a371788bcca7d7
+        .quad   0x636412190eb62a32
+        .quad   0x26907c5c2ecc4e95
+
+        // 2^4 * 1 * G
+
+        .quad   0x7ec851ca553e2df3
+        .quad   0xa71284cba64878b3
+        .quad   0xe6b5e4193288d1e7
+        .quad   0x4cf210ec5a9a8883
+        .quad   0x322d04a52d9021f6
+        .quad   0xb9c19f3375c6bf9c
+        .quad   0x587a3a4342d20b09
+        .quad   0x143b1cf8aa64fe61
+        .quad   0x9f867c7d968acaab
+        .quad   0x5f54258e27092729
+        .quad   0xd0a7d34bea180975
+        .quad   0x21b546a3374126e1
+
+        // 2^4 * 2 * G
+
+        .quad   0xa94ff858a2888343
+        .quad   0xce0ed4565313ed3c
+        .quad   0xf55c3dcfb5bf34fa
+        .quad   0x0a653ca5c9eab371
+        .quad   0x490a7a45d185218f
+        .quad   0x9a15377846049335
+        .quad   0x0060ea09cc31e1f6
+        .quad   0x7e041577f86ee965
+        .quad   0x66b2a496ce5b67f3
+        .quad   0xff5492d8bd569796
+        .quad   0x503cec294a592cd0
+        .quad   0x566943650813acb2
+
+        // 2^4 * 3 * G
+
+        .quad   0xb818db0c26620798
+        .quad   0x5d5c31d9606e354a
+        .quad   0x0982fa4f00a8cdc7
+        .quad   0x17e12bcd4653e2d4
+        .quad   0x5672f9eb1dabb69d
+        .quad   0xba70b535afe853fc
+        .quad   0x47ac0f752796d66d
+        .quad   0x32a5351794117275
+        .quad   0xd3a644a6df648437
+        .quad   0x703b6559880fbfdd
+        .quad   0xcb852540ad3a1aa5
+        .quad   0x0900b3f78e4c6468
+
+        // 2^4 * 4 * G
+
+        .quad   0x0a851b9f679d651b
+        .quad   0xe108cb61033342f2
+        .quad   0xd601f57fe88b30a3
+        .quad   0x371f3acaed2dd714
+        .quad   0xed280fbec816ad31
+        .quad   0x52d9595bd8e6efe3
+        .quad   0x0fe71772f6c623f5
+        .quad   0x4314030b051e293c
+        .quad   0xd560005efbf0bcad
+        .quad   0x8eb70f2ed1870c5e
+        .quad   0x201f9033d084e6a0
+        .quad   0x4c3a5ae1ce7b6670
+
+        // 2^4 * 5 * G
+
+        .quad   0x4138a434dcb8fa95
+        .quad   0x870cf67d6c96840b
+        .quad   0xde388574297be82c
+        .quad   0x7c814db27262a55a
+        .quad   0xbaf875e4c93da0dd
+        .quad   0xb93282a771b9294d
+        .quad   0x80d63fb7f4c6c460
+        .quad   0x6de9c73dea66c181
+        .quad   0x478904d5a04df8f2
+        .quad   0xfafbae4ab10142d3
+        .quad   0xf6c8ac63555d0998
+        .quad   0x5aac4a412f90b104
+
+        // 2^4 * 6 * G
+
+        .quad   0xc64f326b3ac92908
+        .quad   0x5551b282e663e1e0
+        .quad   0x476b35f54a1a4b83
+        .quad   0x1b9da3fe189f68c2
+        .quad   0x603a0d0abd7f5134
+        .quad   0x8089c932e1d3ae46
+        .quad   0xdf2591398798bd63
+        .quad   0x1c145cd274ba0235
+        .quad   0x32e8386475f3d743
+        .quad   0x365b8baf6ae5d9ef
+        .quad   0x825238b6385b681e
+        .quad   0x234929c1167d65e1
+
+        // 2^4 * 7 * G
+
+        .quad   0x984decaba077ade8
+        .quad   0x383f77ad19eb389d
+        .quad   0xc7ec6b7e2954d794
+        .quad   0x59c77b3aeb7c3a7a
+        .quad   0x48145cc21d099fcf
+        .quad   0x4535c192cc28d7e5
+        .quad   0x80e7c1e548247e01
+        .quad   0x4a5f28743b2973ee
+        .quad   0xd3add725225ccf62
+        .quad   0x911a3381b2152c5d
+        .quad   0xd8b39fad5b08f87d
+        .quad   0x6f05606b4799fe3b
+
+        // 2^4 * 8 * G
+
+        .quad   0x9ffe9e92177ba962
+        .quad   0x98aee71d0de5cae1
+        .quad   0x3ff4ae942d831044
+        .quad   0x714de12e58533ac8
+        .quad   0x5b433149f91b6483
+        .quad   0xadb5dc655a2cbf62
+        .quad   0x87fa8412632827b3
+        .quad   0x60895e91ab49f8d8
+        .quad   0xe9ecf2ed0cf86c18
+        .quad   0xb46d06120735dfd4
+        .quad   0xbc9da09804b96be7
+        .quad   0x73e2e62fd96dc26b
+
+        // 2^8 * 1 * G
+
+        .quad   0xed5b635449aa515e
+        .quad   0xa865c49f0bc6823a
+        .quad   0x850c1fe95b42d1c4
+        .quad   0x30d76d6f03d315b9
+        .quad   0x2eccdd0e632f9c1d
+        .quad   0x51d0b69676893115
+        .quad   0x52dfb76ba8637a58
+        .quad   0x6dd37d49a00eef39
+        .quad   0x6c4444172106e4c7
+        .quad   0xfb53d680928d7f69
+        .quad   0xb4739ea4694d3f26
+        .quad   0x10c697112e864bb0
+
+        // 2^8 * 2 * G
+
+        .quad   0x6493c4277dbe5fde
+        .quad   0x265d4fad19ad7ea2
+        .quad   0x0e00dfc846304590
+        .quad   0x25e61cabed66fe09
+        .quad   0x0ca62aa08358c805
+        .quad   0x6a3d4ae37a204247
+        .quad   0x7464d3a63b11eddc
+        .quad   0x03bf9baf550806ef
+        .quad   0x3f13e128cc586604
+        .quad   0x6f5873ecb459747e
+        .quad   0xa0b63dedcc1268f5
+        .quad   0x566d78634586e22c
+
+        // 2^8 * 3 * G
+
+        .quad   0x1637a49f9cc10834
+        .quad   0xbc8e56d5a89bc451
+        .quad   0x1cb5ec0f7f7fd2db
+        .quad   0x33975bca5ecc35d9
+        .quad   0xa1054285c65a2fd0
+        .quad   0x6c64112af31667c3
+        .quad   0x680ae240731aee58
+        .quad   0x14fba5f34793b22a
+        .quad   0x3cd746166985f7d4
+        .quad   0x593e5e84c9c80057
+        .quad   0x2fc3f2b67b61131e
+        .quad   0x14829cea83fc526c
+
+        // 2^8 * 4 * G
+
+        .quad   0xff437b8497dd95c2
+        .quad   0x6c744e30aa4eb5a7
+        .quad   0x9e0c5d613c85e88b
+        .quad   0x2fd9c71e5f758173
+        .quad   0x21e70b2f4e71ecb8
+        .quad   0xe656ddb940a477e3
+        .quad   0xbf6556cece1d4f80
+        .quad   0x05fc3bc4535d7b7e
+        .quad   0x24b8b3ae52afdedd
+        .quad   0x3495638ced3b30cf
+        .quad   0x33a4bc83a9be8195
+        .quad   0x373767475c651f04
+
+        // 2^8 * 5 * G
+
+        .quad   0x2fba99fd40d1add9
+        .quad   0xb307166f96f4d027
+        .quad   0x4363f05215f03bae
+        .quad   0x1fbea56c3b18f999
+        .quad   0x634095cb14246590
+        .quad   0xef12144016c15535
+        .quad   0x9e38140c8910bc60
+        .quad   0x6bf5905730907c8c
+        .quad   0x0fa778f1e1415b8a
+        .quad   0x06409ff7bac3a77e
+        .quad   0x6f52d7b89aa29a50
+        .quad   0x02521cf67a635a56
+
+        // 2^8 * 6 * G
+
+        .quad   0x513fee0b0a9d5294
+        .quad   0x8f98e75c0fdf5a66
+        .quad   0xd4618688bfe107ce
+        .quad   0x3fa00a7e71382ced
+        .quad   0xb1146720772f5ee4
+        .quad   0xe8f894b196079ace
+        .quad   0x4af8224d00ac824a
+        .quad   0x001753d9f7cd6cc4
+        .quad   0x3c69232d963ddb34
+        .quad   0x1dde87dab4973858
+        .quad   0xaad7d1f9a091f285
+        .quad   0x12b5fe2fa048edb6
+
+        // 2^8 * 7 * G
+
+        .quad   0x71f0fbc496fce34d
+        .quad   0x73b9826badf35bed
+        .quad   0xd2047261ff28c561
+        .quad   0x749b76f96fb1206f
+        .quad   0xdf2b7c26ad6f1e92
+        .quad   0x4b66d323504b8913
+        .quad   0x8c409dc0751c8bc3
+        .quad   0x6f7e93c20796c7b8
+        .quad   0x1f5af604aea6ae05
+        .quad   0xc12351f1bee49c99
+        .quad   0x61a808b5eeff6b66
+        .quad   0x0fcec10f01e02151
+
+        // 2^8 * 8 * G
+
+        .quad   0x644d58a649fe1e44
+        .quad   0x21fcaea231ad777e
+        .quad   0x02441c5a887fd0d2
+        .quad   0x4901aa7183c511f3
+        .quad   0x3df2d29dc4244e45
+        .quad   0x2b020e7493d8de0a
+        .quad   0x6cc8067e820c214d
+        .quad   0x413779166feab90a
+        .quad   0x08b1b7548c1af8f0
+        .quad   0xce0f7a7c246299b4
+        .quad   0xf760b0f91e06d939
+        .quad   0x41bb887b726d1213
+
+        // 2^12 * 1 * G
+
+        .quad   0x9267806c567c49d8
+        .quad   0x066d04ccca791e6a
+        .quad   0xa69f5645e3cc394b
+        .quad   0x5c95b686a0788cd2
+        .quad   0x97d980e0aa39f7d2
+        .quad   0x35d0384252c6b51c
+        .quad   0x7d43f49307cd55aa
+        .quad   0x56bd36cfb78ac362
+        .quad   0x2ac519c10d14a954
+        .quad   0xeaf474b494b5fa90
+        .quad   0xe6af8382a9f87a5a
+        .quad   0x0dea6db1879be094
+
+        // 2^12 * 2 * G
+
+        .quad   0xaa66bf547344e5ab
+        .quad   0xda1258888f1b4309
+        .quad   0x5e87d2b3fd564b2f
+        .quad   0x5b2c78885483b1dd
+        .quad   0x15baeb74d6a8797a
+        .quad   0x7ef55cf1fac41732
+        .quad   0x29001f5a3c8b05c5
+        .quad   0x0ad7cc8752eaccfb
+        .quad   0x52151362793408cf
+        .quad   0xeb0f170319963d94
+        .quad   0xa833b2fa883d9466
+        .quad   0x093a7fa775003c78
+
+        // 2^12 * 3 * G
+
+        .quad   0xe5107de63a16d7be
+        .quad   0xa377ffdc9af332cf
+        .quad   0x70d5bf18440b677f
+        .quad   0x6a252b19a4a31403
+        .quad   0xb8e9604460a91286
+        .quad   0x7f3fd8047778d3de
+        .quad   0x67d01e31bf8a5e2d
+        .quad   0x7b038a06c27b653e
+        .quad   0x9ed919d5d36990f3
+        .quad   0x5213aebbdb4eb9f2
+        .quad   0xc708ea054cb99135
+        .quad   0x58ded57f72260e56
+
+        // 2^12 * 4 * G
+
+        .quad   0x78e79dade9413d77
+        .quad   0xf257f9d59729e67d
+        .quad   0x59db910ee37aa7e6
+        .quad   0x6aa11b5bbb9e039c
+        .quad   0xda6d53265b0fd48b
+        .quad   0x8960823193bfa988
+        .quad   0xd78ac93261d57e28
+        .quad   0x79f2942d3a5c8143
+        .quad   0x97da2f25b6c88de9
+        .quad   0x251ba7eaacf20169
+        .quad   0x09b44f87ef4eb4e4
+        .quad   0x7d90ab1bbc6a7da5
+
+        // 2^12 * 5 * G
+
+        .quad   0x9acca683a7016bfe
+        .quad   0x90505f4df2c50b6d
+        .quad   0x6b610d5fcce435aa
+        .quad   0x19a10d446198ff96
+        .quad   0x1a07a3f496b3c397
+        .quad   0x11ceaa188f4e2532
+        .quad   0x7d9498d5a7751bf0
+        .quad   0x19ed161f508dd8a0
+        .quad   0x560a2cd687dce6ca
+        .quad   0x7f3568c48664cf4d
+        .quad   0x8741e95222803a38
+        .quad   0x483bdab1595653fc
+
+        // 2^12 * 6 * G
+
+        .quad   0xfa780f148734fa49
+        .quad   0x106f0b70360534e0
+        .quad   0x2210776fe3e307bd
+        .quad   0x3286c109dde6a0fe
+        .quad   0xd6cf4d0ab4da80f6
+        .quad   0x82483e45f8307fe0
+        .quad   0x05005269ae6f9da4
+        .quad   0x1c7052909cf7877a
+        .quad   0x32ee7de2874e98d4
+        .quad   0x14c362e9b97e0c60
+        .quad   0x5781dcde6a60a38a
+        .quad   0x217dd5eaaa7aa840
+
+        // 2^12 * 7 * G
+
+        .quad   0x9db7c4d0248e1eb0
+        .quad   0xe07697e14d74bf52
+        .quad   0x1e6a9b173c562354
+        .quad   0x7fa7c21f795a4965
+        .quad   0x8bdf1fb9be8c0ec8
+        .quad   0x00bae7f8e30a0282
+        .quad   0x4963991dad6c4f6c
+        .quad   0x07058a6e5df6f60a
+        .quad   0xe9eb02c4db31f67f
+        .quad   0xed25fd8910bcfb2b
+        .quad   0x46c8131f5c5cddb4
+        .quad   0x33b21c13a0cb9bce
+
+        // 2^12 * 8 * G
+
+        .quad   0x360692f8087d8e31
+        .quad   0xf4dcc637d27163f7
+        .quad   0x25a4e62065ea5963
+        .quad   0x659bf72e5ac160d9
+        .quad   0x9aafb9b05ee38c5b
+        .quad   0xbf9d2d4e071a13c7
+        .quad   0x8eee6e6de933290a
+        .quad   0x1c3bab17ae109717
+        .quad   0x1c9ab216c7cab7b0
+        .quad   0x7d65d37407bbc3cc
+        .quad   0x52744750504a58d5
+        .quad   0x09f2606b131a2990
+
+        // 2^16 * 1 * G
+
+        .quad   0x40e87d44744346be
+        .quad   0x1d48dad415b52b25
+        .quad   0x7c3a8a18a13b603e
+        .quad   0x4eb728c12fcdbdf7
+        .quad   0x7e234c597c6691ae
+        .quad   0x64889d3d0a85b4c8
+        .quad   0xdae2c90c354afae7
+        .quad   0x0a871e070c6a9e1d
+        .quad   0x3301b5994bbc8989
+        .quad   0x736bae3a5bdd4260
+        .quad   0x0d61ade219d59e3c
+        .quad   0x3ee7300f2685d464
+
+        // 2^16 * 2 * G
+
+        .quad   0xf5d255e49e7dd6b7
+        .quad   0x8016115c610b1eac
+        .quad   0x3c99975d92e187ca
+        .quad   0x13815762979125c2
+        .quad   0x43fa7947841e7518
+        .quad   0xe5c6fa59639c46d7
+        .quad   0xa1065e1de3052b74
+        .quad   0x7d47c6a2cfb89030
+        .quad   0x3fdad0148ef0d6e0
+        .quad   0x9d3e749a91546f3c
+        .quad   0x71ec621026bb8157
+        .quad   0x148cf58d34c9ec80
+
+        // 2^16 * 3 * G
+
+        .quad   0x46a492f67934f027
+        .quad   0x469984bef6840aa9
+        .quad   0x5ca1bc2a89611854
+        .quad   0x3ff2fa1ebd5dbbd4
+        .quad   0xe2572f7d9ae4756d
+        .quad   0x56c345bb88f3487f
+        .quad   0x9fd10b6d6960a88d
+        .quad   0x278febad4eaea1b9
+        .quad   0xb1aa681f8c933966
+        .quad   0x8c21949c20290c98
+        .quad   0x39115291219d3c52
+        .quad   0x4104dd02fe9c677b
+
+        // 2^16 * 4 * G
+
+        .quad   0x72b2bf5e1124422a
+        .quad   0xa1fa0c3398a33ab5
+        .quad   0x94cb6101fa52b666
+        .quad   0x2c863b00afaf53d5
+        .quad   0x81214e06db096ab8
+        .quad   0x21a8b6c90ce44f35
+        .quad   0x6524c12a409e2af5
+        .quad   0x0165b5a48efca481
+        .quad   0xf190a474a0846a76
+        .quad   0x12eff984cd2f7cc0
+        .quad   0x695e290658aa2b8f
+        .quad   0x591b67d9bffec8b8
+
+        // 2^16 * 5 * G
+
+        .quad   0x312f0d1c80b49bfa
+        .quad   0x5979515eabf3ec8a
+        .quad   0x727033c09ef01c88
+        .quad   0x3de02ec7ca8f7bcb
+        .quad   0x99b9b3719f18b55d
+        .quad   0xe465e5faa18c641e
+        .quad   0x61081136c29f05ed
+        .quad   0x489b4f867030128b
+        .quad   0xd232102d3aeb92ef
+        .quad   0xe16253b46116a861
+        .quad   0x3d7eabe7190baa24
+        .quad   0x49f5fbba496cbebf
+
+        // 2^16 * 6 * G
+
+        .quad   0x30949a108a5bcfd4
+        .quad   0xdc40dd70bc6473eb
+        .quad   0x92c294c1307c0d1c
+        .quad   0x5604a86dcbfa6e74
+        .quad   0x155d628c1e9c572e
+        .quad   0x8a4d86acc5884741
+        .quad   0x91a352f6515763eb
+        .quad   0x06a1a6c28867515b
+        .quad   0x7288d1d47c1764b6
+        .quad   0x72541140e0418b51
+        .quad   0x9f031a6018acf6d1
+        .quad   0x20989e89fe2742c6
+
+        // 2^16 * 7 * G
+
+        .quad   0x499777fd3a2dcc7f
+        .quad   0x32857c2ca54fd892
+        .quad   0xa279d864d207e3a0
+        .quad   0x0403ed1d0ca67e29
+        .quad   0x1674278b85eaec2e
+        .quad   0x5621dc077acb2bdf
+        .quad   0x640a4c1661cbf45a
+        .quad   0x730b9950f70595d3
+        .quad   0xc94b2d35874ec552
+        .quad   0xc5e6c8cf98246f8d
+        .quad   0xf7cb46fa16c035ce
+        .quad   0x5bd7454308303dcc
+
+        // 2^16 * 8 * G
+
+        .quad   0x7f9ad19528b24cc2
+        .quad   0x7f6b54656335c181
+        .quad   0x66b8b66e4fc07236
+        .quad   0x133a78007380ad83
+        .quad   0x85c4932115e7792a
+        .quad   0xc64c89a2bdcdddc9
+        .quad   0x9d1e3da8ada3d762
+        .quad   0x5bb7db123067f82c
+        .quad   0x0961f467c6ca62be
+        .quad   0x04ec21d6211952ee
+        .quad   0x182360779bd54770
+        .quad   0x740dca6d58f0e0d2
+
+        // 2^20 * 1 * G
+
+        .quad   0x50b70bf5d3f0af0b
+        .quad   0x4feaf48ae32e71f7
+        .quad   0x60e84ed3a55bbd34
+        .quad   0x00ed489b3f50d1ed
+        .quad   0x3906c72aed261ae5
+        .quad   0x9ab68fd988e100f7
+        .quad   0xf5e9059af3360197
+        .quad   0x0e53dc78bf2b6d47
+        .quad   0xb90829bf7971877a
+        .quad   0x5e4444636d17e631
+        .quad   0x4d05c52e18276893
+        .quad   0x27632d9a5a4a4af5
+
+        // 2^20 * 2 * G
+
+        .quad   0xd11ff05154b260ce
+        .quad   0xd86dc38e72f95270
+        .quad   0x601fcd0d267cc138
+        .quad   0x2b67916429e90ccd
+        .quad   0xa98285d187eaffdb
+        .quad   0xa5b4fbbbd8d0a864
+        .quad   0xb658f27f022663f7
+        .quad   0x3bbc2b22d99ce282
+        .quad   0xb917c952583c0a58
+        .quad   0x653ff9b80fe4c6f3
+        .quad   0x9b0da7d7bcdf3c0c
+        .quad   0x43a0eeb6ab54d60e
+
+        // 2^20 * 3 * G
+
+        .quad   0x396966a46d4a5487
+        .quad   0xf811a18aac2bb3ba
+        .quad   0x66e4685b5628b26b
+        .quad   0x70a477029d929b92
+        .quad   0x3ac6322357875fe8
+        .quad   0xd9d4f4ecf5fbcb8f
+        .quad   0x8dee8493382bb620
+        .quad   0x50c5eaa14c799fdc
+        .quad   0xdd0edc8bd6f2fb3c
+        .quad   0x54c63aa79cc7b7a0
+        .quad   0xae0b032b2c8d9f1a
+        .quad   0x6f9ce107602967fb
+
+        // 2^20 * 4 * G
+
+        .quad   0xad1054b1cde1c22a
+        .quad   0xc4a8e90248eb32df
+        .quad   0x5f3e7b33accdc0ea
+        .quad   0x72364713fc79963e
+        .quad   0x139693063520e0b5
+        .quad   0x437fcf7c88ea03fe
+        .quad   0xf7d4c40bd3c959bc
+        .quad   0x699154d1f893ded9
+        .quad   0x315d5c75b4b27526
+        .quad   0xcccb842d0236daa5
+        .quad   0x22f0c8a3345fee8e
+        .quad   0x73975a617d39dbed
+
+        // 2^20 * 5 * G
+
+        .quad   0xe4024df96375da10
+        .quad   0x78d3251a1830c870
+        .quad   0x902b1948658cd91c
+        .quad   0x7e18b10b29b7438a
+        .quad   0x6f37f392f4433e46
+        .quad   0x0e19b9a11f566b18
+        .quad   0x220fb78a1fd1d662
+        .quad   0x362a4258a381c94d
+        .quad   0x9071d9132b6beb2f
+        .quad   0x0f26e9ad28418247
+        .quad   0xeab91ec9bdec925d
+        .quad   0x4be65bc8f48af2de
+
+        // 2^20 * 6 * G
+
+        .quad   0x78487feba36e7028
+        .quad   0x5f3f13001dd8ce34
+        .quad   0x934fb12d4b30c489
+        .quad   0x056c244d397f0a2b
+        .quad   0x1d50fba257c26234
+        .quad   0x7bd4823adeb0678b
+        .quad   0xc2b0dc6ea6538af5
+        .quad   0x5665eec6351da73e
+        .quad   0xdb3ee00943bfb210
+        .quad   0x4972018720800ac2
+        .quad   0x26ab5d6173bd8667
+        .quad   0x20b209c2ab204938
+
+        // 2^20 * 7 * G
+
+        .quad   0x549e342ac07fb34b
+        .quad   0x02d8220821373d93
+        .quad   0xbc262d70acd1f567
+        .quad   0x7a92c9fdfbcac784
+        .quad   0x1fcca94516bd3289
+        .quad   0x448d65aa41420428
+        .quad   0x59c3b7b216a55d62
+        .quad   0x49992cc64e612cd8
+        .quad   0x65bd1bea70f801de
+        .quad   0x1befb7c0fe49e28a
+        .quad   0xa86306cdb1b2ae4a
+        .quad   0x3b7ac0cd265c2a09
+
+        // 2^20 * 8 * G
+
+        .quad   0x822bee438c01bcec
+        .quad   0x530cb525c0fbc73b
+        .quad   0x48519034c1953fe9
+        .quad   0x265cc261e09a0f5b
+        .quad   0xf0d54e4f22ed39a7
+        .quad   0xa2aae91e5608150a
+        .quad   0xf421b2e9eddae875
+        .quad   0x31bc531d6b7de992
+        .quad   0xdf3d134da980f971
+        .quad   0x7a4fb8d1221a22a7
+        .quad   0x3df7d42035aad6d8
+        .quad   0x2a14edcc6a1a125e
+
+        // 2^24 * 1 * G
+
+        .quad   0xdf48ee0752cfce4e
+        .quad   0xc3fffaf306ec08b7
+        .quad   0x05710b2ab95459c4
+        .quad   0x161d25fa963ea38d
+        .quad   0x231a8c570478433c
+        .quad   0xb7b5270ec281439d
+        .quad   0xdbaa99eae3d9079f
+        .quad   0x2c03f5256c2b03d9
+        .quad   0x790f18757b53a47d
+        .quad   0x307b0130cf0c5879
+        .quad   0x31903d77257ef7f9
+        .quad   0x699468bdbd96bbaf
+
+        // 2^24 * 2 * G
+
+        .quad   0xbd1f2f46f4dafecf
+        .quad   0x7cef0114a47fd6f7
+        .quad   0xd31ffdda4a47b37f
+        .quad   0x525219a473905785
+        .quad   0xd8dd3de66aa91948
+        .quad   0x485064c22fc0d2cc
+        .quad   0x9b48246634fdea2f
+        .quad   0x293e1c4e6c4a2e3a
+        .quad   0x376e134b925112e1
+        .quad   0x703778b5dca15da0
+        .quad   0xb04589af461c3111
+        .quad   0x5b605c447f032823
+
+        // 2^24 * 3 * G
+
+        .quad   0xb965805920c47c89
+        .quad   0xe7f0100c923b8fcc
+        .quad   0x0001256502e2ef77
+        .quad   0x24a76dcea8aeb3ee
+        .quad   0x3be9fec6f0e7f04c
+        .quad   0x866a579e75e34962
+        .quad   0x5542ef161e1de61a
+        .quad   0x2f12fef4cc5abdd5
+        .quad   0x0a4522b2dfc0c740
+        .quad   0x10d06e7f40c9a407
+        .quad   0xc6cf144178cff668
+        .quad   0x5e607b2518a43790
+
+        // 2^24 * 4 * G
+
+        .quad   0x58b31d8f6cdf1818
+        .quad   0x35cfa74fc36258a2
+        .quad   0xe1b3ff4f66e61d6e
+        .quad   0x5067acab6ccdd5f7
+        .quad   0xa02c431ca596cf14
+        .quad   0xe3c42d40aed3e400
+        .quad   0xd24526802e0f26db
+        .quad   0x201f33139e457068
+        .quad   0xfd527f6b08039d51
+        .quad   0x18b14964017c0006
+        .quad   0xd5220eb02e25a4a8
+        .quad   0x397cba8862460375
+
+        // 2^24 * 5 * G
+
+        .quad   0x30c13093f05959b2
+        .quad   0xe23aa18de9a97976
+        .quad   0x222fd491721d5e26
+        .quad   0x2339d320766e6c3a
+        .quad   0x7815c3fbc81379e7
+        .quad   0xa6619420dde12af1
+        .quad   0xffa9c0f885a8fdd5
+        .quad   0x771b4022c1e1c252
+        .quad   0xd87dd986513a2fa7
+        .quad   0xf5ac9b71f9d4cf08
+        .quad   0xd06bc31b1ea283b3
+        .quad   0x331a189219971a76
+
+        // 2^24 * 6 * G
+
+        .quad   0xf5166f45fb4f80c6
+        .quad   0x9c36c7de61c775cf
+        .quad   0xe3d4e81b9041d91c
+        .quad   0x31167c6b83bdfe21
+        .quad   0x26512f3a9d7572af
+        .quad   0x5bcbe28868074a9e
+        .quad   0x84edc1c11180f7c4
+        .quad   0x1ac9619ff649a67b
+        .quad   0xf22b3842524b1068
+        .quad   0x5068343bee9ce987
+        .quad   0xfc9d71844a6250c8
+        .quad   0x612436341f08b111
+
+        // 2^24 * 7 * G
+
+        .quad   0xd99d41db874e898d
+        .quad   0x09fea5f16c07dc20
+        .quad   0x793d2c67d00f9bbc
+        .quad   0x46ebe2309e5eff40
+        .quad   0x8b6349e31a2d2638
+        .quad   0x9ddfb7009bd3fd35
+        .quad   0x7f8bf1b8a3a06ba4
+        .quad   0x1522aa3178d90445
+        .quad   0x2c382f5369614938
+        .quad   0xdafe409ab72d6d10
+        .quad   0xe8c83391b646f227
+        .quad   0x45fe70f50524306c
+
+        // 2^24 * 8 * G
+
+        .quad   0xda4875a6960c0b8c
+        .quad   0x5b68d076ef0e2f20
+        .quad   0x07fb51cf3d0b8fd4
+        .quad   0x428d1623a0e392d4
+        .quad   0x62f24920c8951491
+        .quad   0x05f007c83f630ca2
+        .quad   0x6fbb45d2f5c9d4b8
+        .quad   0x16619f6db57a2245
+        .quad   0x084f4a4401a308fd
+        .quad   0xa82219c376a5caac
+        .quad   0xdeb8de4643d1bc7d
+        .quad   0x1d81592d60bd38c6
+
+        // 2^28 * 1 * G
+
+        .quad   0xd833d7beec2a4c38
+        .quad   0x2c9162830acc20ed
+        .quad   0xe93a47aa92df7581
+        .quad   0x702d67a3333c4a81
+        .quad   0x3a4a369a2f89c8a1
+        .quad   0x63137a1d7c8de80d
+        .quad   0xbcac008a78eda015
+        .quad   0x2cb8b3a5b483b03f
+        .quad   0x36e417cbcb1b90a1
+        .quad   0x33b3ddaa7f11794e
+        .quad   0x3f510808885bc607
+        .quad   0x24141dc0e6a8020d
+
+        // 2^28 * 2 * G
+
+        .quad   0x59f73c773fefee9d
+        .quad   0xb3f1ef89c1cf989d
+        .quad   0xe35dfb42e02e545f
+        .quad   0x5766120b47a1b47c
+        .quad   0x91925dccbd83157d
+        .quad   0x3ca1205322cc8094
+        .quad   0x28e57f183f90d6e4
+        .quad   0x1a4714cede2e767b
+        .quad   0xdb20ba0fb8b6b7ff
+        .quad   0xb732c3b677511fa1
+        .quad   0xa92b51c099f02d89
+        .quad   0x4f3875ad489ca5f1
+
+        // 2^28 * 3 * G
+
+        .quad   0xc7fc762f4932ab22
+        .quad   0x7ac0edf72f4c3c1b
+        .quad   0x5f6b55aa9aa895e8
+        .quad   0x3680274dad0a0081
+        .quad   0x79ed13f6ee73eec0
+        .quad   0xa5c6526d69110bb1
+        .quad   0xe48928c38603860c
+        .quad   0x722a1446fd7059f5
+        .quad   0xd0959fe9a8cf8819
+        .quad   0xd0a995508475a99c
+        .quad   0x6eac173320b09cc5
+        .quad   0x628ecf04331b1095
+
+        // 2^28 * 4 * G
+
+        .quad   0x98bcb118a9d0ddbc
+        .quad   0xee449e3408b4802b
+        .quad   0x87089226b8a6b104
+        .quad   0x685f349a45c7915d
+        .quad   0x9b41acf85c74ccf1
+        .quad   0xb673318108265251
+        .quad   0x99c92aed11adb147
+        .quad   0x7a47d70d34ecb40f
+        .quad   0x60a0c4cbcc43a4f5
+        .quad   0x775c66ca3677bea9
+        .quad   0xa17aa1752ff8f5ed
+        .quad   0x11ded9020e01fdc0
+
+        // 2^28 * 5 * G
+
+        .quad   0x890e7809caefe704
+        .quad   0x8728296de30e8c6c
+        .quad   0x4c5cd2a392aeb1c9
+        .quad   0x194263d15771531f
+        .quad   0x471f95b03bea93b7
+        .quad   0x0552d7d43313abd3
+        .quad   0xbd9370e2e17e3f7b
+        .quad   0x7b120f1db20e5bec
+        .quad   0x17d2fb3d86502d7a
+        .quad   0xb564d84450a69352
+        .quad   0x7da962c8a60ed75d
+        .quad   0x00d0f85b318736aa
+
+        // 2^28 * 6 * G
+
+        .quad   0x978b142e777c84fd
+        .quad   0xf402644705a8c062
+        .quad   0xa67ad51be7e612c7
+        .quad   0x2f7b459698dd6a33
+        .quad   0xa6753c1efd7621c1
+        .quad   0x69c0b4a7445671f5
+        .quad   0x971f527405b23c11
+        .quad   0x387bc74851a8c7cd
+        .quad   0x81894b4d4a52a9a8
+        .quad   0xadd93e12f6b8832f
+        .quad   0x184d8548b61bd638
+        .quad   0x3f1c62dbd6c9f6cd
+
+        // 2^28 * 7 * G
+
+        .quad   0x2e8f1f0091910c1f
+        .quad   0xa4df4fe0bff2e12c
+        .quad   0x60c6560aee927438
+        .quad   0x6338283facefc8fa
+        .quad   0x3fad3e40148f693d
+        .quad   0x052656e194eb9a72
+        .quad   0x2f4dcbfd184f4e2f
+        .quad   0x406f8db1c482e18b
+        .quad   0x9e630d2c7f191ee4
+        .quad   0x4fbf8301bc3ff670
+        .quad   0x787d8e4e7afb73c4
+        .quad   0x50d83d5be8f58fa5
+
+        // 2^28 * 8 * G
+
+        .quad   0x85683916c11a1897
+        .quad   0x2d69a4efe506d008
+        .quad   0x39af1378f664bd01
+        .quad   0x65942131361517c6
+        .quad   0xc0accf90b4d3b66d
+        .quad   0xa7059de561732e60
+        .quad   0x033d1f7870c6b0ba
+        .quad   0x584161cd26d946e4
+        .quad   0xbbf2b1a072d27ca2
+        .quad   0xbf393c59fbdec704
+        .quad   0xe98dbbcee262b81e
+        .quad   0x02eebd0b3029b589
+
+        // 2^32 * 1 * G
+
+        .quad   0x61368756a60dac5f
+        .quad   0x17e02f6aebabdc57
+        .quad   0x7f193f2d4cce0f7d
+        .quad   0x20234a7789ecdcf0
+        .quad   0x8765b69f7b85c5e8
+        .quad   0x6ff0678bd168bab2
+        .quad   0x3a70e77c1d330f9b
+        .quad   0x3a5f6d51b0af8e7c
+        .quad   0x76d20db67178b252
+        .quad   0x071c34f9d51ed160
+        .quad   0xf62a4a20b3e41170
+        .quad   0x7cd682353cffe366
+
+        // 2^32 * 2 * G
+
+        .quad   0x0be1a45bd887fab6
+        .quad   0x2a846a32ba403b6e
+        .quad   0xd9921012e96e6000
+        .quad   0x2838c8863bdc0943
+        .quad   0xa665cd6068acf4f3
+        .quad   0x42d92d183cd7e3d3
+        .quad   0x5759389d336025d9
+        .quad   0x3ef0253b2b2cd8ff
+        .quad   0xd16bb0cf4a465030
+        .quad   0xfa496b4115c577ab
+        .quad   0x82cfae8af4ab419d
+        .quad   0x21dcb8a606a82812
+
+        // 2^32 * 3 * G
+
+        .quad   0x5c6004468c9d9fc8
+        .quad   0x2540096ed42aa3cb
+        .quad   0x125b4d4c12ee2f9c
+        .quad   0x0bc3d08194a31dab
+        .quad   0x9a8d00fabe7731ba
+        .quad   0x8203607e629e1889
+        .quad   0xb2cc023743f3d97f
+        .quad   0x5d840dbf6c6f678b
+        .quad   0x706e380d309fe18b
+        .quad   0x6eb02da6b9e165c7
+        .quad   0x57bbba997dae20ab
+        .quad   0x3a4276232ac196dd
+
+        // 2^32 * 4 * G
+
+        .quad   0x4b42432c8a7084fa
+        .quad   0x898a19e3dfb9e545
+        .quad   0xbe9f00219c58e45d
+        .quad   0x1ff177cea16debd1
+        .quad   0x3bf8c172db447ecb
+        .quad   0x5fcfc41fc6282dbd
+        .quad   0x80acffc075aa15fe
+        .quad   0x0770c9e824e1a9f9
+        .quad   0xcf61d99a45b5b5fd
+        .quad   0x860984e91b3a7924
+        .quad   0xe7300919303e3e89
+        .quad   0x39f264fd41500b1e
+
+        // 2^32 * 5 * G
+
+        .quad   0xa7ad3417dbe7e29c
+        .quad   0xbd94376a2b9c139c
+        .quad   0xa0e91b8e93597ba9
+        .quad   0x1712d73468889840
+        .quad   0xd19b4aabfe097be1
+        .quad   0xa46dfce1dfe01929
+        .quad   0xc3c908942ca6f1ff
+        .quad   0x65c621272c35f14e
+        .quad   0xe72b89f8ce3193dd
+        .quad   0x4d103356a125c0bb
+        .quad   0x0419a93d2e1cfe83
+        .quad   0x22f9800ab19ce272
+
+        // 2^32 * 6 * G
+
+        .quad   0x605a368a3e9ef8cb
+        .quad   0xe3e9c022a5504715
+        .quad   0x553d48b05f24248f
+        .quad   0x13f416cd647626e5
+        .quad   0x42029fdd9a6efdac
+        .quad   0xb912cebe34a54941
+        .quad   0x640f64b987bdf37b
+        .quad   0x4171a4d38598cab4
+        .quad   0xfa2758aa99c94c8c
+        .quad   0x23006f6fb000b807
+        .quad   0xfbd291ddadda5392
+        .quad   0x508214fa574bd1ab
+
+        // 2^32 * 7 * G
+
+        .quad   0xc20269153ed6fe4b
+        .quad   0xa65a6739511d77c4
+        .quad   0xcbde26462c14af94
+        .quad   0x22f960ec6faba74b
+        .quad   0x461a15bb53d003d6
+        .quad   0xb2102888bcf3c965
+        .quad   0x27c576756c683a5a
+        .quad   0x3a7758a4c86cb447
+        .quad   0x548111f693ae5076
+        .quad   0x1dae21df1dfd54a6
+        .quad   0x12248c90f3115e65
+        .quad   0x5d9fd15f8de7f494
+
+        // 2^32 * 8 * G
+
+        .quad   0x031408d36d63727f
+        .quad   0x6a379aefd7c7b533
+        .quad   0xa9e18fc5ccaee24b
+        .quad   0x332f35914f8fbed3
+        .quad   0x3f244d2aeed7521e
+        .quad   0x8e3a9028432e9615
+        .quad   0xe164ba772e9c16d4
+        .quad   0x3bc187fa47eb98d8
+        .quad   0x6d470115ea86c20c
+        .quad   0x998ab7cb6c46d125
+        .quad   0xd77832b53a660188
+        .quad   0x450d81ce906fba03
+
+        // 2^36 * 1 * G
+
+        .quad   0xf8ae4d2ad8453902
+        .quad   0x7018058ee8db2d1d
+        .quad   0xaab3995fc7d2c11e
+        .quad   0x53b16d2324ccca79
+        .quad   0x23264d66b2cae0b5
+        .quad   0x7dbaed33ebca6576
+        .quad   0x030ebed6f0d24ac8
+        .quad   0x2a887f78f7635510
+        .quad   0x2a23b9e75c012d4f
+        .quad   0x0c974651cae1f2ea
+        .quad   0x2fb63273675d70ca
+        .quad   0x0ba7250b864403f5
+
+        // 2^36 * 2 * G
+
+        .quad   0xbb0d18fd029c6421
+        .quad   0xbc2d142189298f02
+        .quad   0x8347f8e68b250e96
+        .quad   0x7b9f2fe8032d71c9
+        .quad   0xdd63589386f86d9c
+        .quad   0x61699176e13a85a4
+        .quad   0x2e5111954eaa7d57
+        .quad   0x32c21b57fb60bdfb
+        .quad   0xd87823cd319e0780
+        .quad   0xefc4cfc1897775c5
+        .quad   0x4854fb129a0ab3f7
+        .quad   0x12c49d417238c371
+
+        // 2^36 * 3 * G
+
+        .quad   0x0950b533ffe83769
+        .quad   0x21861c1d8e1d6bd1
+        .quad   0xf022d8381302e510
+        .quad   0x2509200c6391cab4
+        .quad   0x09b3a01783799542
+        .quad   0x626dd08faad5ee3f
+        .quad   0xba00bceeeb70149f
+        .quad   0x1421b246a0a444c9
+        .quad   0x4aa43a8e8c24a7c7
+        .quad   0x04c1f540d8f05ef5
+        .quad   0xadba5e0c0b3eb9dc
+        .quad   0x2ab5504448a49ce3
+
+        // 2^36 * 4 * G
+
+        .quad   0x2ed227266f0f5dec
+        .quad   0x9824ee415ed50824
+        .quad   0x807bec7c9468d415
+        .quad   0x7093bae1b521e23f
+        .quad   0xdc07ac631c5d3afa
+        .quad   0x58615171f9df8c6c
+        .quad   0x72a079d89d73e2b0
+        .quad   0x7301f4ceb4eae15d
+        .quad   0x6409e759d6722c41
+        .quad   0xa674e1cf72bf729b
+        .quad   0xbc0a24eb3c21e569
+        .quad   0x390167d24ebacb23
+
+        // 2^36 * 5 * G
+
+        .quad   0x27f58e3bba353f1c
+        .quad   0x4c47764dbf6a4361
+        .quad   0xafbbc4e56e562650
+        .quad   0x07db2ee6aae1a45d
+        .quad   0xd7bb054ba2f2120b
+        .quad   0xe2b9ceaeb10589b7
+        .quad   0x3fe8bac8f3c0edbe
+        .quad   0x4cbd40767112cb69
+        .quad   0x0b603cc029c58176
+        .quad   0x5988e3825cb15d61
+        .quad   0x2bb61413dcf0ad8d
+        .quad   0x7b8eec6c74183287
+
+        // 2^36 * 6 * G
+
+        .quad   0xe4ca40782cd27cb0
+        .quad   0xdaf9c323fbe967bd
+        .quad   0xb29bd34a8ad41e9e
+        .quad   0x72810497626ede4d
+        .quad   0x32fee570fc386b73
+        .quad   0xda8b0141da3a8cc7
+        .quad   0x975ffd0ac8968359
+        .quad   0x6ee809a1b132a855
+        .quad   0x9444bb31fcfd863a
+        .quad   0x2fe3690a3e4e48c5
+        .quad   0xdc29c867d088fa25
+        .quad   0x13bd1e38d173292e
+
+        // 2^36 * 7 * G
+
+        .quad   0xd32b4cd8696149b5
+        .quad   0xe55937d781d8aab7
+        .quad   0x0bcb2127ae122b94
+        .quad   0x41e86fcfb14099b0
+        .quad   0x223fb5cf1dfac521
+        .quad   0x325c25316f554450
+        .quad   0x030b98d7659177ac
+        .quad   0x1ed018b64f88a4bd
+        .quad   0x3630dfa1b802a6b0
+        .quad   0x880f874742ad3bd5
+        .quad   0x0af90d6ceec5a4d4
+        .quad   0x746a247a37cdc5d9
+
+        // 2^36 * 8 * G
+
+        .quad   0xd531b8bd2b7b9af6
+        .quad   0x5005093537fc5b51
+        .quad   0x232fcf25c593546d
+        .quad   0x20a365142bb40f49
+        .quad   0x6eccd85278d941ed
+        .quad   0x2254ae83d22f7843
+        .quad   0xc522d02e7bbfcdb7
+        .quad   0x681e3351bff0e4e2
+        .quad   0x8b64b59d83034f45
+        .quad   0x2f8b71f21fa20efb
+        .quad   0x69249495ba6550e4
+        .quad   0x539ef98e45d5472b
+
+        // 2^40 * 1 * G
+
+        .quad   0x6e7bb6a1a6205275
+        .quad   0xaa4f21d7413c8e83
+        .quad   0x6f56d155e88f5cb2
+        .quad   0x2de25d4ba6345be1
+        .quad   0xd074d8961cae743f
+        .quad   0xf86d18f5ee1c63ed
+        .quad   0x97bdc55be7f4ed29
+        .quad   0x4cbad279663ab108
+        .quad   0x80d19024a0d71fcd
+        .quad   0xc525c20afb288af8
+        .quad   0xb1a3974b5f3a6419
+        .quad   0x7d7fbcefe2007233
+
+        // 2^40 * 2 * G
+
+        .quad   0xfaef1e6a266b2801
+        .quad   0x866c68c4d5739f16
+        .quad   0xf68a2fbc1b03762c
+        .quad   0x5975435e87b75a8d
+        .quad   0xcd7c5dc5f3c29094
+        .quad   0xc781a29a2a9105ab
+        .quad   0x80c61d36421c3058
+        .quad   0x4f9cd196dcd8d4d7
+        .quad   0x199297d86a7b3768
+        .quad   0xd0d058241ad17a63
+        .quad   0xba029cad5c1c0c17
+        .quad   0x7ccdd084387a0307
+
+        // 2^40 * 3 * G
+
+        .quad   0xdca6422c6d260417
+        .quad   0xae153d50948240bd
+        .quad   0xa9c0c1b4fb68c677
+        .quad   0x428bd0ed61d0cf53
+        .quad   0x9b0c84186760cc93
+        .quad   0xcdae007a1ab32a99
+        .quad   0xa88dec86620bda18
+        .quad   0x3593ca848190ca44
+        .quad   0x9213189a5e849aa7
+        .quad   0xd4d8c33565d8facd
+        .quad   0x8c52545b53fdbbd1
+        .quad   0x27398308da2d63e6
+
+        // 2^40 * 4 * G
+
+        .quad   0x42c38d28435ed413
+        .quad   0xbd50f3603278ccc9
+        .quad   0xbb07ab1a79da03ef
+        .quad   0x269597aebe8c3355
+        .quad   0xb9a10e4c0a702453
+        .quad   0x0fa25866d57d1bde
+        .quad   0xffb9d9b5cd27daf7
+        .quad   0x572c2945492c33fd
+        .quad   0xc77fc745d6cd30be
+        .quad   0xe4dfe8d3e3baaefb
+        .quad   0xa22c8830aa5dda0c
+        .quad   0x7f985498c05bca80
+
+        // 2^40 * 5 * G
+
+        .quad   0x3849ce889f0be117
+        .quad   0x8005ad1b7b54a288
+        .quad   0x3da3c39f23fc921c
+        .quad   0x76c2ec470a31f304
+        .quad   0xd35615520fbf6363
+        .quad   0x08045a45cf4dfba6
+        .quad   0xeec24fbc873fa0c2
+        .quad   0x30f2653cd69b12e7
+        .quad   0x8a08c938aac10c85
+        .quad   0x46179b60db276bcb
+        .quad   0xa920c01e0e6fac70
+        .quad   0x2f1273f1596473da
+
+        // 2^40 * 6 * G
+
+        .quad   0x4739fc7c8ae01e11
+        .quad   0xfd5274904a6aab9f
+        .quad   0x41d98a8287728f2e
+        .quad   0x5d9e572ad85b69f2
+        .quad   0x30488bd755a70bc0
+        .quad   0x06d6b5a4f1d442e7
+        .quad   0xead1a69ebc596162
+        .quad   0x38ac1997edc5f784
+        .quad   0x0666b517a751b13b
+        .quad   0x747d06867e9b858c
+        .quad   0xacacc011454dde49
+        .quad   0x22dfcd9cbfe9e69c
+
+        // 2^40 * 7 * G
+
+        .quad   0x8ddbd2e0c30d0cd9
+        .quad   0xad8e665facbb4333
+        .quad   0x8f6b258c322a961f
+        .quad   0x6b2916c05448c1c7
+        .quad   0x56ec59b4103be0a1
+        .quad   0x2ee3baecd259f969
+        .quad   0x797cb29413f5cd32
+        .quad   0x0fe9877824cde472
+        .quad   0x7edb34d10aba913b
+        .quad   0x4ea3cd822e6dac0e
+        .quad   0x66083dff6578f815
+        .quad   0x4c303f307ff00a17
+
+        // 2^40 * 8 * G
+
+        .quad   0xd30a3bd617b28c85
+        .quad   0xc5d377b739773bea
+        .quad   0xc6c6e78c1e6a5cbf
+        .quad   0x0d61b8f78b2ab7c4
+        .quad   0x29fc03580dd94500
+        .quad   0xecd27aa46fbbec93
+        .quad   0x130a155fc2e2a7f8
+        .quad   0x416b151ab706a1d5
+        .quad   0x56a8d7efe9c136b0
+        .quad   0xbd07e5cd58e44b20
+        .quad   0xafe62fda1b57e0ab
+        .quad   0x191a2af74277e8d2
+
+        // 2^44 * 1 * G
+
+        .quad   0xd550095bab6f4985
+        .quad   0x04f4cd5b4fbfaf1a
+        .quad   0x9d8e2ed12a0c7540
+        .quad   0x2bc24e04b2212286
+        .quad   0x09d4b60b2fe09a14
+        .quad   0xc384f0afdbb1747e
+        .quad   0x58e2ea8978b5fd6e
+        .quad   0x519ef577b5e09b0a
+        .quad   0x1863d7d91124cca9
+        .quad   0x7ac08145b88a708e
+        .quad   0x2bcd7309857031f5
+        .quad   0x62337a6e8ab8fae5
+
+        // 2^44 * 2 * G
+
+        .quad   0x4bcef17f06ffca16
+        .quad   0xde06e1db692ae16a
+        .quad   0x0753702d614f42b0
+        .quad   0x5f6041b45b9212d0
+        .quad   0xd1ab324e1b3a1273
+        .quad   0x18947cf181055340
+        .quad   0x3b5d9567a98c196e
+        .quad   0x7fa00425802e1e68
+        .quad   0x7d531574028c2705
+        .quad   0x80317d69db0d75fe
+        .quad   0x30fface8ef8c8ddd
+        .quad   0x7e9de97bb6c3e998
+
+        // 2^44 * 3 * G
+
+        .quad   0x1558967b9e6585a3
+        .quad   0x97c99ce098e98b92
+        .quad   0x10af149b6eb3adad
+        .quad   0x42181fe8f4d38cfa
+        .quad   0xf004be62a24d40dd
+        .quad   0xba0659910452d41f
+        .quad   0x81c45ee162a44234
+        .quad   0x4cb829d8a22266ef
+        .quad   0x1dbcaa8407b86681
+        .quad   0x081f001e8b26753b
+        .quad   0x3cd7ce6a84048e81
+        .quad   0x78af11633f25f22c
+
+        // 2^44 * 4 * G
+
+        .quad   0x8416ebd40b50babc
+        .quad   0x1508722628208bee
+        .quad   0xa3148fafb9c1c36d
+        .quad   0x0d07daacd32d7d5d
+        .quad   0x3241c00e7d65318c
+        .quad   0xe6bee5dcd0e86de7
+        .quad   0x118b2dc2fbc08c26
+        .quad   0x680d04a7fc603dc3
+        .quad   0xf9c2414a695aa3eb
+        .quad   0xdaa42c4c05a68f21
+        .quad   0x7c6c23987f93963e
+        .quad   0x210e8cd30c3954e3
+
+        // 2^44 * 5 * G
+
+        .quad   0xac4201f210a71c06
+        .quad   0x6a65e0aef3bfb021
+        .quad   0xbc42c35c393632f7
+        .quad   0x56ea8db1865f0742
+        .quad   0x2b50f16137fe6c26
+        .quad   0xe102bcd856e404d8
+        .quad   0x12b0f1414c561f6b
+        .quad   0x51b17bc8d028ec91
+        .quad   0xfff5fb4bcf535119
+        .quad   0xf4989d79df1108a0
+        .quad   0xbdfcea659a3ba325
+        .quad   0x18a11f1174d1a6f2
+
+        // 2^44 * 6 * G
+
+        .quad   0x407375ab3f6bba29
+        .quad   0x9ec3b6d8991e482e
+        .quad   0x99c80e82e55f92e9
+        .quad   0x307c13b6fb0c0ae1
+        .quad   0xfbd63cdad27a5f2c
+        .quad   0xf00fc4bc8aa106d7
+        .quad   0x53fb5c1a8e64a430
+        .quad   0x04eaabe50c1a2e85
+        .quad   0x24751021cb8ab5e7
+        .quad   0xfc2344495c5010eb
+        .quad   0x5f1e717b4e5610a1
+        .quad   0x44da5f18c2710cd5
+
+        // 2^44 * 7 * G
+
+        .quad   0x033cc55ff1b82eb5
+        .quad   0xb15ae36d411cae52
+        .quad   0xba40b6198ffbacd3
+        .quad   0x768edce1532e861f
+        .quad   0x9156fe6b89d8eacc
+        .quad   0xe6b79451e23126a1
+        .quad   0xbd7463d93944eb4e
+        .quad   0x726373f6767203ae
+        .quad   0xe305ca72eb7ef68a
+        .quad   0x662cf31f70eadb23
+        .quad   0x18f026fdb4c45b68
+        .quad   0x513b5384b5d2ecbd
+
+        // 2^44 * 8 * G
+
+        .quad   0x46d46280c729989e
+        .quad   0x4b93fbd05368a5dd
+        .quad   0x63df3f81d1765a89
+        .quad   0x34cebd64b9a0a223
+        .quad   0x5e2702878af34ceb
+        .quad   0x900b0409b946d6ae
+        .quad   0x6512ebf7dabd8512
+        .quad   0x61d9b76988258f81
+        .quad   0xa6c5a71349b7d94b
+        .quad   0xa3f3d15823eb9446
+        .quad   0x0416fbd277484834
+        .quad   0x69d45e6f2c70812f
+
+        // 2^48 * 1 * G
+
+        .quad   0xce16f74bc53c1431
+        .quad   0x2b9725ce2072edde
+        .quad   0xb8b9c36fb5b23ee7
+        .quad   0x7e2e0e450b5cc908
+        .quad   0x9fe62b434f460efb
+        .quad   0xded303d4a63607d6
+        .quad   0xf052210eb7a0da24
+        .quad   0x237e7dbe00545b93
+        .quad   0x013575ed6701b430
+        .quad   0x231094e69f0bfd10
+        .quad   0x75320f1583e47f22
+        .quad   0x71afa699b11155e3
+
+        // 2^48 * 2 * G
+
+        .quad   0x65ce6f9b3953b61d
+        .quad   0xc65839eaafa141e6
+        .quad   0x0f435ffda9f759fe
+        .quad   0x021142e9c2b1c28e
+        .quad   0xea423c1c473b50d6
+        .quad   0x51e87a1f3b38ef10
+        .quad   0x9b84bf5fb2c9be95
+        .quad   0x00731fbc78f89a1c
+        .quad   0xe430c71848f81880
+        .quad   0xbf960c225ecec119
+        .quad   0xb6dae0836bba15e3
+        .quad   0x4c4d6f3347e15808
+
+        // 2^48 * 3 * G
+
+        .quad   0x18f7eccfc17d1fc9
+        .quad   0x6c75f5a651403c14
+        .quad   0xdbde712bf7ee0cdf
+        .quad   0x193fddaaa7e47a22
+        .quad   0x2f0cddfc988f1970
+        .quad   0x6b916227b0b9f51b
+        .quad   0x6ec7b6c4779176be
+        .quad   0x38bf9500a88f9fa8
+        .quad   0x1fd2c93c37e8876f
+        .quad   0xa2f61e5a18d1462c
+        .quad   0x5080f58239241276
+        .quad   0x6a6fb99ebf0d4969
+
+        // 2^48 * 4 * G
+
+        .quad   0x6a46c1bb560855eb
+        .quad   0x2416bb38f893f09d
+        .quad   0xd71d11378f71acc1
+        .quad   0x75f76914a31896ea
+        .quad   0xeeb122b5b6e423c6
+        .quad   0x939d7010f286ff8e
+        .quad   0x90a92a831dcf5d8c
+        .quad   0x136fda9f42c5eb10
+        .quad   0xf94cdfb1a305bdd1
+        .quad   0x0f364b9d9ff82c08
+        .quad   0x2a87d8a5c3bb588a
+        .quad   0x022183510be8dcba
+
+        // 2^48 * 5 * G
+
+        .quad   0x4af766385ead2d14
+        .quad   0xa08ed880ca7c5830
+        .quad   0x0d13a6e610211e3d
+        .quad   0x6a071ce17b806c03
+        .quad   0x9d5a710143307a7f
+        .quad   0xb063de9ec47da45f
+        .quad   0x22bbfe52be927ad3
+        .quad   0x1387c441fd40426c
+        .quad   0xb5d3c3d187978af8
+        .quad   0x722b5a3d7f0e4413
+        .quad   0x0d7b4848bb477ca0
+        .quad   0x3171b26aaf1edc92
+
+        // 2^48 * 6 * G
+
+        .quad   0xa92f319097564ca8
+        .quad   0xff7bb84c2275e119
+        .quad   0x4f55fe37a4875150
+        .quad   0x221fd4873cf0835a
+        .quad   0xa60db7d8b28a47d1
+        .quad   0xa6bf14d61770a4f1
+        .quad   0xd4a1f89353ddbd58
+        .quad   0x6c514a63344243e9
+        .quad   0x2322204f3a156341
+        .quad   0xfb73e0e9ba0a032d
+        .quad   0xfce0dd4c410f030e
+        .quad   0x48daa596fb924aaa
+
+        // 2^48 * 7 * G
+
+        .quad   0x6eca8e665ca59cc7
+        .quad   0xa847254b2e38aca0
+        .quad   0x31afc708d21e17ce
+        .quad   0x676dd6fccad84af7
+        .quad   0x14f61d5dc84c9793
+        .quad   0x9941f9e3ef418206
+        .quad   0xcdf5b88f346277ac
+        .quad   0x58c837fa0e8a79a9
+        .quad   0x0cf9688596fc9058
+        .quad   0x1ddcbbf37b56a01b
+        .quad   0xdcc2e77d4935d66a
+        .quad   0x1c4f73f2c6a57f0a
+
+        // 2^48 * 8 * G
+
+        .quad   0x0e7a4fbd305fa0bb
+        .quad   0x829d4ce054c663ad
+        .quad   0xf421c3832fe33848
+        .quad   0x795ac80d1bf64c42
+        .quad   0xb36e706efc7c3484
+        .quad   0x73dfc9b4c3c1cf61
+        .quad   0xeb1d79c9781cc7e5
+        .quad   0x70459adb7daf675c
+        .quad   0x1b91db4991b42bb3
+        .quad   0x572696234b02dcca
+        .quad   0x9fdf9ee51f8c78dc
+        .quad   0x5fe162848ce21fd3
+
+        // 2^52 * 1 * G
+
+        .quad   0xe2790aae4d077c41
+        .quad   0x8b938270db7469a3
+        .quad   0x6eb632dc8abd16a2
+        .quad   0x720814ecaa064b72
+        .quad   0x315c29c795115389
+        .quad   0xd7e0e507862f74ce
+        .quad   0x0c4a762185927432
+        .quad   0x72de6c984a25a1e4
+        .quad   0xae9ab553bf6aa310
+        .quad   0x050a50a9806d6e1b
+        .quad   0x92bb7403adff5139
+        .quad   0x0394d27645be618b
+
+        // 2^52 * 2 * G
+
+        .quad   0x4d572251857eedf4
+        .quad   0xe3724edde19e93c5
+        .quad   0x8a71420e0b797035
+        .quad   0x3b3c833687abe743
+        .quad   0xf5396425b23545a4
+        .quad   0x15a7a27e98fbb296
+        .quad   0xab6c52bc636fdd86
+        .quad   0x79d995a8419334ee
+        .quad   0xcd8a8ea61195dd75
+        .quad   0xa504d8a81dd9a82f
+        .quad   0x540dca81a35879b6
+        .quad   0x60dd16a379c86a8a
+
+        // 2^52 * 3 * G
+
+        .quad   0x35a2c8487381e559
+        .quad   0x596ffea6d78082cb
+        .quad   0xcb9771ebdba7b653
+        .quad   0x5a08b5019b4da685
+        .quad   0x3501d6f8153e47b8
+        .quad   0xb7a9675414a2f60c
+        .quad   0x112ee8b6455d9523
+        .quad   0x4e62a3c18112ea8a
+        .quad   0xc8d4ac04516ab786
+        .quad   0x595af3215295b23d
+        .quad   0xd6edd234db0230c1
+        .quad   0x0929efe8825b41cc
+
+        // 2^52 * 4 * G
+
+        .quad   0x5f0601d1cbd0f2d3
+        .quad   0x736e412f6132bb7f
+        .quad   0x83604432238dde87
+        .quad   0x1e3a5272f5c0753c
+        .quad   0x8b3172b7ad56651d
+        .quad   0x01581b7a3fabd717
+        .quad   0x2dc94df6424df6e4
+        .quad   0x30376e5d2c29284f
+        .quad   0xd2918da78159a59c
+        .quad   0x6bdc1cd93f0713f3
+        .quad   0x565f7a934acd6590
+        .quad   0x53daacec4cb4c128
+
+        // 2^52 * 5 * G
+
+        .quad   0x4ca73bd79cc8a7d6
+        .quad   0x4d4a738f47e9a9b2
+        .quad   0xf4cbf12942f5fe00
+        .quad   0x01a13ff9bdbf0752
+        .quad   0x99852bc3852cfdb0
+        .quad   0x2cc12e9559d6ed0b
+        .quad   0x70f9e2bf9b5ac27b
+        .quad   0x4f3b8c117959ae99
+        .quad   0x55b6c9c82ff26412
+        .quad   0x1ac4a8c91fb667a8
+        .quad   0xd527bfcfeb778bf2
+        .quad   0x303337da7012a3be
+
+        // 2^52 * 6 * G
+
+        .quad   0x955422228c1c9d7c
+        .quad   0x01fac1371a9b340f
+        .quad   0x7e8d9177925b48d7
+        .quad   0x53f8ad5661b3e31b
+        .quad   0x976d3ccbfad2fdd1
+        .quad   0xcb88839737a640a8
+        .quad   0x2ff00c1d6734cb25
+        .quad   0x269ff4dc789c2d2b
+        .quad   0x0c003fbdc08d678d
+        .quad   0x4d982fa37ead2b17
+        .quad   0xc07e6bcdb2e582f1
+        .quad   0x296c7291df412a44
+
+        // 2^52 * 7 * G
+
+        .quad   0x7903de2b33daf397
+        .quad   0xd0ff0619c9a624b3
+        .quad   0x8a1d252b555b3e18
+        .quad   0x2b6d581c52e0b7c0
+        .quad   0xdfb23205dab8b59e
+        .quad   0x465aeaa0c8092250
+        .quad   0xd133c1189a725d18
+        .quad   0x2327370261f117d1
+        .quad   0x3d0543d3623e7986
+        .quad   0x679414c2c278a354
+        .quad   0xae43f0cc726196f6
+        .quad   0x7836c41f8245eaba
+
+        // 2^52 * 8 * G
+
+        .quad   0xe7a254db49e95a81
+        .quad   0x5192d5d008b0ad73
+        .quad   0x4d20e5b1d00afc07
+        .quad   0x5d55f8012cf25f38
+        .quad   0xca651e848011937c
+        .quad   0xc6b0c46e6ef41a28
+        .quad   0xb7021ba75f3f8d52
+        .quad   0x119dff99ead7b9fd
+        .quad   0x43eadfcbf4b31d4d
+        .quad   0xc6503f7411148892
+        .quad   0xfeee68c5060d3b17
+        .quad   0x329293b3dd4a0ac8
+
+        // 2^56 * 1 * G
+
+        .quad   0x4e59214fe194961a
+        .quad   0x49be7dc70d71cd4f
+        .quad   0x9300cfd23b50f22d
+        .quad   0x4789d446fc917232
+        .quad   0x2879852d5d7cb208
+        .quad   0xb8dedd70687df2e7
+        .quad   0xdc0bffab21687891
+        .quad   0x2b44c043677daa35
+        .quad   0x1a1c87ab074eb78e
+        .quad   0xfac6d18e99daf467
+        .quad   0x3eacbbcd484f9067
+        .quad   0x60c52eef2bb9a4e4
+
+        // 2^56 * 2 * G
+
+        .quad   0x0b5d89bc3bfd8bf1
+        .quad   0xb06b9237c9f3551a
+        .quad   0x0e4c16b0d53028f5
+        .quad   0x10bc9c312ccfcaab
+        .quad   0x702bc5c27cae6d11
+        .quad   0x44c7699b54a48cab
+        .quad   0xefbc4056ba492eb2
+        .quad   0x70d77248d9b6676d
+        .quad   0xaa8ae84b3ec2a05b
+        .quad   0x98699ef4ed1781e0
+        .quad   0x794513e4708e85d1
+        .quad   0x63755bd3a976f413
+
+        // 2^56 * 3 * G
+
+        .quad   0xb55fa03e2ad10853
+        .quad   0x356f75909ee63569
+        .quad   0x9ff9f1fdbe69b890
+        .quad   0x0d8cc1c48bc16f84
+        .quad   0x3dc7101897f1acb7
+        .quad   0x5dda7d5ec165bbd8
+        .quad   0x508e5b9c0fa1020f
+        .quad   0x2763751737c52a56
+        .quad   0x029402d36eb419a9
+        .quad   0xf0b44e7e77b460a5
+        .quad   0xcfa86230d43c4956
+        .quad   0x70c2dd8a7ad166e7
+
+        // 2^56 * 4 * G
+
+        .quad   0x656194509f6fec0e
+        .quad   0xee2e7ea946c6518d
+        .quad   0x9733c1f367e09b5c
+        .quad   0x2e0fac6363948495
+        .quad   0x91d4967db8ed7e13
+        .quad   0x74252f0ad776817a
+        .quad   0xe40982e00d852564
+        .quad   0x32b8613816a53ce5
+        .quad   0x79e7f7bee448cd64
+        .quad   0x6ac83a67087886d0
+        .quad   0xf89fd4d9a0e4db2e
+        .quad   0x4179215c735a4f41
+
+        // 2^56 * 5 * G
+
+        .quad   0x8c7094e7d7dced2a
+        .quad   0x97fb8ac347d39c70
+        .quad   0xe13be033a906d902
+        .quad   0x700344a30cd99d76
+        .quad   0xe4ae33b9286bcd34
+        .quad   0xb7ef7eb6559dd6dc
+        .quad   0x278b141fb3d38e1f
+        .quad   0x31fa85662241c286
+        .quad   0xaf826c422e3622f4
+        .quad   0xc12029879833502d
+        .quad   0x9bc1b7e12b389123
+        .quad   0x24bb2312a9952489
+
+        // 2^56 * 6 * G
+
+        .quad   0xb1a8ed1732de67c3
+        .quad   0x3cb49418461b4948
+        .quad   0x8ebd434376cfbcd2
+        .quad   0x0fee3e871e188008
+        .quad   0x41f80c2af5f85c6b
+        .quad   0x687284c304fa6794
+        .quad   0x8945df99a3ba1bad
+        .quad   0x0d1d2af9ffeb5d16
+        .quad   0xa9da8aa132621edf
+        .quad   0x30b822a159226579
+        .quad   0x4004197ba79ac193
+        .quad   0x16acd79718531d76
+
+        // 2^56 * 7 * G
+
+        .quad   0x72df72af2d9b1d3d
+        .quad   0x63462a36a432245a
+        .quad   0x3ecea07916b39637
+        .quad   0x123e0ef6b9302309
+        .quad   0xc959c6c57887b6ad
+        .quad   0x94e19ead5f90feba
+        .quad   0x16e24e62a342f504
+        .quad   0x164ed34b18161700
+        .quad   0x487ed94c192fe69a
+        .quad   0x61ae2cea3a911513
+        .quad   0x877bf6d3b9a4de27
+        .quad   0x78da0fc61073f3eb
+
+        // 2^56 * 8 * G
+
+        .quad   0x5bf15d28e52bc66a
+        .quad   0x2c47e31870f01a8e
+        .quad   0x2419afbc06c28bdd
+        .quad   0x2d25deeb256b173a
+        .quad   0xa29f80f1680c3a94
+        .quad   0x71f77e151ae9e7e6
+        .quad   0x1100f15848017973
+        .quad   0x054aa4b316b38ddd
+        .quad   0xdfc8468d19267cb8
+        .quad   0x0b28789c66e54daf
+        .quad   0x2aeb1d2a666eec17
+        .quad   0x134610a6ab7da760
+
+        // 2^60 * 1 * G
+
+        .quad   0xcaf55ec27c59b23f
+        .quad   0x99aeed3e154d04f2
+        .quad   0x68441d72e14141f4
+        .quad   0x140345133932a0a2
+        .quad   0xd91430e0dc028c3c
+        .quad   0x0eb955a85217c771
+        .quad   0x4b09e1ed2c99a1fa
+        .quad   0x42881af2bd6a743c
+        .quad   0x7bfec69aab5cad3d
+        .quad   0xc23e8cd34cb2cfad
+        .quad   0x685dd14bfb37d6a2
+        .quad   0x0ad6d64415677a18
+
+        // 2^60 * 2 * G
+
+        .quad   0x781a439e417becb5
+        .quad   0x4ac5938cd10e0266
+        .quad   0x5da385110692ac24
+        .quad   0x11b065a2ade31233
+        .quad   0x7914892847927e9f
+        .quad   0x33dad6ef370aa877
+        .quad   0x1f8f24fa11122703
+        .quad   0x5265ac2f2adf9592
+        .quad   0x405fdd309afcb346
+        .quad   0xd9723d4428e63f54
+        .quad   0x94c01df05f65aaae
+        .quad   0x43e4dc3ae14c0809
+
+        // 2^60 * 3 * G
+
+        .quad   0xbc12c7f1a938a517
+        .quad   0x473028ab3180b2e1
+        .quad   0x3f78571efbcd254a
+        .quad   0x74e534426ff6f90f
+        .quad   0xea6f7ac3adc2c6a3
+        .quad   0xd0e928f6e9717c94
+        .quad   0xe2d379ead645eaf5
+        .quad   0x46dd8785c51ffbbe
+        .quad   0x709801be375c8898
+        .quad   0x4b06dab5e3fd8348
+        .quad   0x75880ced27230714
+        .quad   0x2b09468fdd2f4c42
+
+        // 2^60 * 4 * G
+
+        .quad   0x97c749eeb701cb96
+        .quad   0x83f438d4b6a369c3
+        .quad   0x62962b8b9a402cd9
+        .quad   0x6976c7509888df7b
+        .quad   0x5b97946582ffa02a
+        .quad   0xda096a51fea8f549
+        .quad   0xa06351375f77af9b
+        .quad   0x1bcfde61201d1e76
+        .quad   0x4a4a5490246a59a2
+        .quad   0xd63ebddee87fdd90
+        .quad   0xd9437c670d2371fa
+        .quad   0x69e87308d30f8ed6
+
+        // 2^60 * 5 * G
+
+        .quad   0x435a8bb15656beb0
+        .quad   0xf8fac9ba4f4d5bca
+        .quad   0xb9b278c41548c075
+        .quad   0x3eb0ef76e892b622
+        .quad   0x0f80bf028bc80303
+        .quad   0x6aae16b37a18cefb
+        .quad   0xdd47ea47d72cd6a3
+        .quad   0x61943588f4ed39aa
+        .quad   0xd26e5c3e91039f85
+        .quad   0xc0e9e77df6f33aa9
+        .quad   0xe8968c5570066a93
+        .quad   0x3c34d1881faaaddd
+
+        // 2^60 * 6 * G
+
+        .quad   0x3f9d2b5ea09f9ec0
+        .quad   0x1dab3b6fb623a890
+        .quad   0xa09ba3ea72d926c4
+        .quad   0x374193513fd8b36d
+        .quad   0xbd5b0b8f2fffe0d9
+        .quad   0x6aa254103ed24fb9
+        .quad   0x2ac7d7bcb26821c4
+        .quad   0x605b394b60dca36a
+        .quad   0xb4e856e45a9d1ed2
+        .quad   0xefe848766c97a9a2
+        .quad   0xb104cf641e5eee7d
+        .quad   0x2f50b81c88a71c8f
+
+        // 2^60 * 7 * G
+
+        .quad   0x31723c61fc6811bb
+        .quad   0x9cb450486211800f
+        .quad   0x768933d347995753
+        .quad   0x3491a53502752fcd
+        .quad   0x2b552ca0a7da522a
+        .quad   0x3230b336449b0250
+        .quad   0xf2c4c5bca4b99fb9
+        .quad   0x7b2c674958074a22
+        .quad   0xd55165883ed28cdf
+        .quad   0x12d84fd2d362de39
+        .quad   0x0a874ad3e3378e4f
+        .quad   0x000d2b1f7c763e74
+
+        // 2^60 * 8 * G
+
+        .quad   0x3d420811d06d4a67
+        .quad   0xbefc048590e0ffe3
+        .quad   0xf870c6b7bd487bde
+        .quad   0x6e2a7316319afa28
+        .quad   0x9624778c3e94a8ab
+        .quad   0x0ad6f3cee9a78bec
+        .quad   0x948ac7810d743c4f
+        .quad   0x76627935aaecfccc
+        .quad   0x56a8ac24d6d59a9f
+        .quad   0xc8db753e3096f006
+        .quad   0x477f41e68f4c5299
+        .quad   0x588d851cf6c86114
+
+        // 2^64 * 1 * G
+
+        .quad   0x51138ec78df6b0fe
+        .quad   0x5397da89e575f51b
+        .quad   0x09207a1d717af1b9
+        .quad   0x2102fdba2b20d650
+        .quad   0xcd2a65e777d1f515
+        .quad   0x548991878faa60f1
+        .quad   0xb1b73bbcdabc06e5
+        .quad   0x654878cba97cc9fb
+        .quad   0x969ee405055ce6a1
+        .quad   0x36bca7681251ad29
+        .quad   0x3a1af517aa7da415
+        .quad   0x0ad725db29ecb2ba
+
+        // 2^64 * 2 * G
+
+        .quad   0xdc4267b1834e2457
+        .quad   0xb67544b570ce1bc5
+        .quad   0x1af07a0bf7d15ed7
+        .quad   0x4aefcffb71a03650
+        .quad   0xfec7bc0c9b056f85
+        .quad   0x537d5268e7f5ffd7
+        .quad   0x77afc6624312aefa
+        .quad   0x4f675f5302399fd9
+        .quad   0xc32d36360415171e
+        .quad   0xcd2bef118998483b
+        .quad   0x870a6eadd0945110
+        .quad   0x0bccbb72a2a86561
+
+        // 2^64 * 3 * G
+
+        .quad   0x185e962feab1a9c8
+        .quad   0x86e7e63565147dcd
+        .quad   0xb092e031bb5b6df2
+        .quad   0x4024f0ab59d6b73e
+        .quad   0x186d5e4c50fe1296
+        .quad   0xe0397b82fee89f7e
+        .quad   0x3bc7f6c5507031b0
+        .quad   0x6678fd69108f37c2
+        .quad   0x1586fa31636863c2
+        .quad   0x07f68c48572d33f2
+        .quad   0x4f73cc9f789eaefc
+        .quad   0x2d42e2108ead4701
+
+        // 2^64 * 4 * G
+
+        .quad   0x97f5131594dfd29b
+        .quad   0x6155985d313f4c6a
+        .quad   0xeba13f0708455010
+        .quad   0x676b2608b8d2d322
+        .quad   0x21717b0d0f537593
+        .quad   0x914e690b131e064c
+        .quad   0x1bb687ae752ae09f
+        .quad   0x420bf3a79b423c6e
+        .quad   0x8138ba651c5b2b47
+        .quad   0x8671b6ec311b1b80
+        .quad   0x7bff0cb1bc3135b0
+        .quad   0x745d2ffa9c0cf1e0
+
+        // 2^64 * 5 * G
+
+        .quad   0xbf525a1e2bc9c8bd
+        .quad   0xea5b260826479d81
+        .quad   0xd511c70edf0155db
+        .quad   0x1ae23ceb960cf5d0
+        .quad   0x6036df5721d34e6a
+        .quad   0xb1db8827997bb3d0
+        .quad   0xd3c209c3c8756afa
+        .quad   0x06e15be54c1dc839
+        .quad   0x5b725d871932994a
+        .quad   0x32351cb5ceb1dab0
+        .quad   0x7dc41549dab7ca05
+        .quad   0x58ded861278ec1f7
+
+        // 2^64 * 6 * G
+
+        .quad   0xd8173793f266c55c
+        .quad   0xc8c976c5cc454e49
+        .quad   0x5ce382f8bc26c3a8
+        .quad   0x2ff39de85485f6f9
+        .quad   0x2dfb5ba8b6c2c9a8
+        .quad   0x48eeef8ef52c598c
+        .quad   0x33809107f12d1573
+        .quad   0x08ba696b531d5bd8
+        .quad   0x77ed3eeec3efc57a
+        .quad   0x04e05517d4ff4811
+        .quad   0xea3d7a3ff1a671cb
+        .quad   0x120633b4947cfe54
+
+        // 2^64 * 7 * G
+
+        .quad   0x0b94987891610042
+        .quad   0x4ee7b13cecebfae8
+        .quad   0x70be739594f0a4c0
+        .quad   0x35d30a99b4d59185
+        .quad   0x82bd31474912100a
+        .quad   0xde237b6d7e6fbe06
+        .quad   0xe11e761911ea79c6
+        .quad   0x07433be3cb393bde
+        .quad   0xff7944c05ce997f4
+        .quad   0x575d3de4b05c51a3
+        .quad   0x583381fd5a76847c
+        .quad   0x2d873ede7af6da9f
+
+        // 2^64 * 8 * G
+
+        .quad   0x157a316443373409
+        .quad   0xfab8b7eef4aa81d9
+        .quad   0xb093fee6f5a64806
+        .quad   0x2e773654707fa7b6
+        .quad   0xaa6202e14e5df981
+        .quad   0xa20d59175015e1f5
+        .quad   0x18a275d3bae21d6c
+        .quad   0x0543618a01600253
+        .quad   0x0deabdf4974c23c1
+        .quad   0xaa6f0a259dce4693
+        .quad   0x04202cb8a29aba2c
+        .quad   0x4b1443362d07960d
+
+        // 2^68 * 1 * G
+
+        .quad   0x47b837f753242cec
+        .quad   0x256dc48cc04212f2
+        .quad   0xe222fbfbe1d928c5
+        .quad   0x48ea295bad8a2c07
+        .quad   0x299b1c3f57c5715e
+        .quad   0x96cb929e6b686d90
+        .quad   0x3004806447235ab3
+        .quad   0x2c435c24a44d9fe1
+        .quad   0x0607c97c80f8833f
+        .quad   0x0e851578ca25ec5b
+        .quad   0x54f7450b161ebb6f
+        .quad   0x7bcb4792a0def80e
+
+        // 2^68 * 2 * G
+
+        .quad   0x8487e3d02bc73659
+        .quad   0x4baf8445059979df
+        .quad   0xd17c975adcad6fbf
+        .quad   0x57369f0bdefc96b6
+        .quad   0x1cecd0a0045224c2
+        .quad   0x757f1b1b69e53952
+        .quad   0x775b7a925289f681
+        .quad   0x1b6cc62016736148
+        .quad   0xf1a9990175638698
+        .quad   0x353dd1beeeaa60d3
+        .quad   0x849471334c9ba488
+        .quad   0x63fa6e6843ade311
+
+        // 2^68 * 3 * G
+
+        .quad   0xd15c20536597c168
+        .quad   0x9f73740098d28789
+        .quad   0x18aee7f13257ba1f
+        .quad   0x3418bfda07346f14
+        .quad   0x2195becdd24b5eb7
+        .quad   0x5e41f18cc0cd44f9
+        .quad   0xdf28074441ca9ede
+        .quad   0x07073b98f35b7d67
+        .quad   0xd03c676c4ce530d4
+        .quad   0x0b64c0473b5df9f4
+        .quad   0x065cef8b19b3a31e
+        .quad   0x3084d661533102c9
+
+        // 2^68 * 4 * G
+
+        .quad   0xe1f6b79ebf8469ad
+        .quad   0x15801004e2663135
+        .quad   0x9a498330af74181b
+        .quad   0x3ba2504f049b673c
+        .quad   0x9a6ce876760321fd
+        .quad   0x7fe2b5109eb63ad8
+        .quad   0x00e7d4ae8ac80592
+        .quad   0x73d86b7abb6f723a
+        .quad   0x0b52b5606dba5ab6
+        .quad   0xa9134f0fbbb1edab
+        .quad   0x30a9520d9b04a635
+        .quad   0x6813b8f37973e5db
+
+        // 2^68 * 5 * G
+
+        .quad   0x9854b054334127c1
+        .quad   0x105d047882fbff25
+        .quad   0xdb49f7f944186f4f
+        .quad   0x1768e838bed0b900
+        .quad   0xf194ca56f3157e29
+        .quad   0x136d35705ef528a5
+        .quad   0xdd4cef778b0599bc
+        .quad   0x7d5472af24f833ed
+        .quad   0xd0ef874daf33da47
+        .quad   0x00d3be5db6e339f9
+        .quad   0x3f2a8a2f9c9ceece
+        .quad   0x5d1aeb792352435a
+
+        // 2^68 * 6 * G
+
+        .quad   0xf59e6bb319cd63ca
+        .quad   0x670c159221d06839
+        .quad   0xb06d565b2150cab6
+        .quad   0x20fb199d104f12a3
+        .quad   0x12c7bfaeb61ba775
+        .quad   0xb84e621fe263bffd
+        .quad   0x0b47a5c35c840dcf
+        .quad   0x7e83be0bccaf8634
+        .quad   0x61943dee6d99c120
+        .quad   0x86101f2e460b9fe0
+        .quad   0x6bb2f1518ee8598d
+        .quad   0x76b76289fcc475cc
+
+        // 2^68 * 7 * G
+
+        .quad   0x791b4cc1756286fa
+        .quad   0xdbced317d74a157c
+        .quad   0x7e732421ea72bde6
+        .quad   0x01fe18491131c8e9
+        .quad   0x4245f1a1522ec0b3
+        .quad   0x558785b22a75656d
+        .quad   0x1d485a2548a1b3c0
+        .quad   0x60959eccd58fe09f
+        .quad   0x3ebfeb7ba8ed7a09
+        .quad   0x49fdc2bbe502789c
+        .quad   0x44ebce5d3c119428
+        .quad   0x35e1eb55be947f4a
+
+        // 2^68 * 8 * G
+
+        .quad   0xdbdae701c5738dd3
+        .quad   0xf9c6f635b26f1bee
+        .quad   0x61e96a8042f15ef4
+        .quad   0x3aa1d11faf60a4d8
+        .quad   0x14fd6dfa726ccc74
+        .quad   0x3b084cfe2f53b965
+        .quad   0xf33ae4f552a2c8b4
+        .quad   0x59aab07a0d40166a
+        .quad   0x77bcec4c925eac25
+        .quad   0x1848718460137738
+        .quad   0x5b374337fea9f451
+        .quad   0x1865e78ec8e6aa46
+
+        // 2^72 * 1 * G
+
+        .quad   0xccc4b7c7b66e1f7a
+        .quad   0x44157e25f50c2f7e
+        .quad   0x3ef06dfc713eaf1c
+        .quad   0x582f446752da63f7
+        .quad   0x967c54e91c529ccb
+        .quad   0x30f6269264c635fb
+        .quad   0x2747aff478121965
+        .quad   0x17038418eaf66f5c
+        .quad   0xc6317bd320324ce4
+        .quad   0xa81042e8a4488bc4
+        .quad   0xb21ef18b4e5a1364
+        .quad   0x0c2a1c4bcda28dc9
+
+        // 2^72 * 2 * G
+
+        .quad   0xd24dc7d06f1f0447
+        .quad   0xb2269e3edb87c059
+        .quad   0xd15b0272fbb2d28f
+        .quad   0x7c558bd1c6f64877
+        .quad   0xedc4814869bd6945
+        .quad   0x0d6d907dbe1c8d22
+        .quad   0xc63bd212d55cc5ab
+        .quad   0x5a6a9b30a314dc83
+        .quad   0xd0ec1524d396463d
+        .quad   0x12bb628ac35a24f0
+        .quad   0xa50c3a791cbc5fa4
+        .quad   0x0404a5ca0afbafc3
+
+        // 2^72 * 3 * G
+
+        .quad   0x8c1f40070aa743d6
+        .quad   0xccbad0cb5b265ee8
+        .quad   0x574b046b668fd2de
+        .quad   0x46395bfdcadd9633
+        .quad   0x62bc9e1b2a416fd1
+        .quad   0xb5c6f728e350598b
+        .quad   0x04343fd83d5d6967
+        .quad   0x39527516e7f8ee98
+        .quad   0x117fdb2d1a5d9a9c
+        .quad   0x9c7745bcd1005c2a
+        .quad   0xefd4bef154d56fea
+        .quad   0x76579a29e822d016
+
+        // 2^72 * 4 * G
+
+        .quad   0x45b68e7e49c02a17
+        .quad   0x23cd51a2bca9a37f
+        .quad   0x3ed65f11ec224c1b
+        .quad   0x43a384dc9e05bdb1
+        .quad   0x333cb51352b434f2
+        .quad   0xd832284993de80e1
+        .quad   0xb5512887750d35ce
+        .quad   0x02c514bb2a2777c1
+        .quad   0x684bd5da8bf1b645
+        .quad   0xfb8bd37ef6b54b53
+        .quad   0x313916d7a9b0d253
+        .quad   0x1160920961548059
+
+        // 2^72 * 5 * G
+
+        .quad   0xb44d166929dacfaa
+        .quad   0xda529f4c8413598f
+        .quad   0xe9ef63ca453d5559
+        .quad   0x351e125bc5698e0b
+        .quad   0x7a385616369b4dcd
+        .quad   0x75c02ca7655c3563
+        .quad   0x7dc21bf9d4f18021
+        .quad   0x2f637d7491e6e042
+        .quad   0xd4b49b461af67bbe
+        .quad   0xd603037ac8ab8961
+        .quad   0x71dee19ff9a699fb
+        .quad   0x7f182d06e7ce2a9a
+
+        // 2^72 * 6 * G
+
+        .quad   0x7a7c8e64ab0168ec
+        .quad   0xcb5a4a5515edc543
+        .quad   0x095519d347cd0eda
+        .quad   0x67d4ac8c343e93b0
+        .quad   0x09454b728e217522
+        .quad   0xaa58e8f4d484b8d8
+        .quad   0xd358254d7f46903c
+        .quad   0x44acc043241c5217
+        .quad   0x1c7d6bbb4f7a5777
+        .quad   0x8b35fed4918313e1
+        .quad   0x4adca1c6c96b4684
+        .quad   0x556d1c8312ad71bd
+
+        // 2^72 * 7 * G
+
+        .quad   0x17ef40e30c8d3982
+        .quad   0x31f7073e15a3fa34
+        .quad   0x4f21f3cb0773646e
+        .quad   0x746c6c6d1d824eff
+        .quad   0x81f06756b11be821
+        .quad   0x0faff82310a3f3dd
+        .quad   0xf8b2d0556a99465d
+        .quad   0x097abe38cc8c7f05
+        .quad   0x0c49c9877ea52da4
+        .quad   0x4c4369559bdc1d43
+        .quad   0x022c3809f7ccebd2
+        .quad   0x577e14a34bee84bd
+
+        // 2^72 * 8 * G
+
+        .quad   0xf0e268ac61a73b0a
+        .quad   0xf2fafa103791a5f5
+        .quad   0xc1e13e826b6d00e9
+        .quad   0x60fa7ee96fd78f42
+        .quad   0x94fecebebd4dd72b
+        .quad   0xf46a4fda060f2211
+        .quad   0x124a5977c0c8d1ff
+        .quad   0x705304b8fb009295
+        .quad   0xb63d1d354d296ec6
+        .quad   0xf3c3053e5fad31d8
+        .quad   0x670b958cb4bd42ec
+        .quad   0x21398e0ca16353fd
+
+        // 2^76 * 1 * G
+
+        .quad   0x216ab2ca8da7d2ef
+        .quad   0x366ad9dd99f42827
+        .quad   0xae64b9004fdd3c75
+        .quad   0x403a395b53909e62
+        .quad   0x86c5fc16861b7e9a
+        .quad   0xf6a330476a27c451
+        .quad   0x01667267a1e93597
+        .quad   0x05ffb9cd6082dfeb
+        .quad   0xa617fa9ff53f6139
+        .quad   0x60f2b5e513e66cb6
+        .quad   0xd7a8beefb3448aa4
+        .quad   0x7a2932856f5ea192
+
+        // 2^76 * 2 * G
+
+        .quad   0x0b39d761b02de888
+        .quad   0x5f550e7ed2414e1f
+        .quad   0xa6bfa45822e1a940
+        .quad   0x050a2f7dfd447b99
+        .quad   0xb89c444879639302
+        .quad   0x4ae4f19350c67f2c
+        .quad   0xf0b35da8c81af9c6
+        .quad   0x39d0003546871017
+        .quad   0x437c3b33a650db77
+        .quad   0x6bafe81dbac52bb2
+        .quad   0xfe99402d2db7d318
+        .quad   0x2b5b7eec372ba6ce
+
+        // 2^76 * 3 * G
+
+        .quad   0xb3bc4bbd83f50eef
+        .quad   0x508f0c998c927866
+        .quad   0x43e76587c8b7e66e
+        .quad   0x0f7655a3a47f98d9
+        .quad   0xa694404d613ac8f4
+        .quad   0x500c3c2bfa97e72c
+        .quad   0x874104d21fcec210
+        .quad   0x1b205fb38604a8ee
+        .quad   0x55ecad37d24b133c
+        .quad   0x441e147d6038c90b
+        .quad   0x656683a1d62c6fee
+        .quad   0x0157d5dc87e0ecae
+
+        // 2^76 * 4 * G
+
+        .quad   0xf2a7af510354c13d
+        .quad   0xd7a0b145aa372b60
+        .quad   0x2869b96a05a3d470
+        .quad   0x6528e42d82460173
+        .quad   0x95265514d71eb524
+        .quad   0xe603d8815df14593
+        .quad   0x147cdf410d4de6b7
+        .quad   0x5293b1730437c850
+        .quad   0x23d0e0814bccf226
+        .quad   0x92c745cd8196fb93
+        .quad   0x8b61796c59541e5b
+        .quad   0x40a44df0c021f978
+
+        // 2^76 * 5 * G
+
+        .quad   0xdaa869894f20ea6a
+        .quad   0xea14a3d14c620618
+        .quad   0x6001fccb090bf8be
+        .quad   0x35f4e822947e9cf0
+        .quad   0x86c96e514bc5d095
+        .quad   0xf20d4098fca6804a
+        .quad   0x27363d89c826ea5d
+        .quad   0x39ca36565719cacf
+        .quad   0x97506f2f6f87b75c
+        .quad   0xc624aea0034ae070
+        .quad   0x1ec856e3aad34dd6
+        .quad   0x055b0be0e440e58f
+
+        // 2^76 * 6 * G
+
+        .quad   0x6469a17d89735d12
+        .quad   0xdb6f27d5e662b9f1
+        .quad   0x9fcba3286a395681
+        .quad   0x363b8004d269af25
+        .quad   0x4d12a04b6ea33da2
+        .quad   0x57cf4c15e36126dd
+        .quad   0x90ec9675ee44d967
+        .quad   0x64ca348d2a985aac
+        .quad   0x99588e19e4c4912d
+        .quad   0xefcc3b4e1ca5ce6b
+        .quad   0x4522ea60fa5b98d5
+        .quad   0x7064bbab1de4a819
+
+        // 2^76 * 7 * G
+
+        .quad   0xb919e1515a770641
+        .quad   0xa9a2e2c74e7f8039
+        .quad   0x7527250b3df23109
+        .quad   0x756a7330ac27b78b
+        .quad   0xa290c06142542129
+        .quad   0xf2e2c2aebe8d5b90
+        .quad   0xcf2458db76abfe1b
+        .quad   0x02157ade83d626bf
+        .quad   0x3e46972a1b9a038b
+        .quad   0x2e4ee66a7ee03fb4
+        .quad   0x81a248776edbb4ca
+        .quad   0x1a944ee88ecd0563
+
+        // 2^76 * 8 * G
+
+        .quad   0xd5a91d1151039372
+        .quad   0x2ed377b799ca26de
+        .quad   0xa17202acfd366b6b
+        .quad   0x0730291bd6901995
+        .quad   0xbb40a859182362d6
+        .quad   0xb99f55778a4d1abb
+        .quad   0x8d18b427758559f6
+        .quad   0x26c20fe74d26235a
+        .quad   0x648d1d9fe9cc22f5
+        .quad   0x66bc561928dd577c
+        .quad   0x47d3ed21652439d1
+        .quad   0x49d271acedaf8b49
+
+        // 2^80 * 1 * G
+
+        .quad   0x89f5058a382b33f3
+        .quad   0x5ae2ba0bad48c0b4
+        .quad   0x8f93b503a53db36e
+        .quad   0x5aa3ed9d95a232e6
+        .quad   0x2798aaf9b4b75601
+        .quad   0x5eac72135c8dad72
+        .quad   0xd2ceaa6161b7a023
+        .quad   0x1bbfb284e98f7d4e
+        .quad   0x656777e9c7d96561
+        .quad   0xcb2b125472c78036
+        .quad   0x65053299d9506eee
+        .quad   0x4a07e14e5e8957cc
+
+        // 2^80 * 2 * G
+
+        .quad   0x4ee412cb980df999
+        .quad   0xa315d76f3c6ec771
+        .quad   0xbba5edde925c77fd
+        .quad   0x3f0bac391d313402
+        .quad   0x240b58cdc477a49b
+        .quad   0xfd38dade6447f017
+        .quad   0x19928d32a7c86aad
+        .quad   0x50af7aed84afa081
+        .quad   0x6e4fde0115f65be5
+        .quad   0x29982621216109b2
+        .quad   0x780205810badd6d9
+        .quad   0x1921a316baebd006
+
+        // 2^80 * 3 * G
+
+        .quad   0x89422f7edfb870fc
+        .quad   0x2c296beb4f76b3bd
+        .quad   0x0738f1d436c24df7
+        .quad   0x6458df41e273aeb0
+        .quad   0xd75aad9ad9f3c18b
+        .quad   0x566a0eef60b1c19c
+        .quad   0x3e9a0bac255c0ed9
+        .quad   0x7b049deca062c7f5
+        .quad   0xdccbe37a35444483
+        .quad   0x758879330fedbe93
+        .quad   0x786004c312c5dd87
+        .quad   0x6093dccbc2950e64
+
+        // 2^80 * 4 * G
+
+        .quad   0x1ff39a8585e0706d
+        .quad   0x36d0a5d8b3e73933
+        .quad   0x43b9f2e1718f453b
+        .quad   0x57d1ea084827a97c
+        .quad   0x6bdeeebe6084034b
+        .quad   0x3199c2b6780fb854
+        .quad   0x973376abb62d0695
+        .quad   0x6e3180c98b647d90
+        .quad   0xee7ab6e7a128b071
+        .quad   0xa4c1596d93a88baa
+        .quad   0xf7b4de82b2216130
+        .quad   0x363e999ddd97bd18
+
+        // 2^80 * 5 * G
+
+        .quad   0x96a843c135ee1fc4
+        .quad   0x976eb35508e4c8cf
+        .quad   0xb42f6801b58cd330
+        .quad   0x48ee9b78693a052b
+        .quad   0x2f1848dce24baec6
+        .quad   0x769b7255babcaf60
+        .quad   0x90cb3c6e3cefe931
+        .quad   0x231f979bc6f9b355
+        .quad   0x5c31de4bcc2af3c6
+        .quad   0xb04bb030fe208d1f
+        .quad   0xb78d7009c14fb466
+        .quad   0x079bfa9b08792413
+
+        // 2^80 * 6 * G
+
+        .quad   0xe3903a51da300df4
+        .quad   0x843964233da95ab0
+        .quad   0xed3cf12d0b356480
+        .quad   0x038c77f684817194
+        .quad   0xf3c9ed80a2d54245
+        .quad   0x0aa08b7877f63952
+        .quad   0xd76dac63d1085475
+        .quad   0x1ef4fb159470636b
+        .quad   0x854e5ee65b167bec
+        .quad   0x59590a4296d0cdc2
+        .quad   0x72b2df3498102199
+        .quad   0x575ee92a4a0bff56
+
+        // 2^80 * 7 * G
+
+        .quad   0xd4c080908a182fcf
+        .quad   0x30e170c299489dbd
+        .quad   0x05babd5752f733de
+        .quad   0x43d4e7112cd3fd00
+        .quad   0x5d46bc450aa4d801
+        .quad   0xc3af1227a533b9d8
+        .quad   0x389e3b262b8906c2
+        .quad   0x200a1e7e382f581b
+        .quad   0x518db967eaf93ac5
+        .quad   0x71bc989b056652c0
+        .quad   0xfe2b85d9567197f5
+        .quad   0x050eca52651e4e38
+
+        // 2^80 * 8 * G
+
+        .quad   0xc3431ade453f0c9c
+        .quad   0xe9f5045eff703b9b
+        .quad   0xfcd97ac9ed847b3d
+        .quad   0x4b0ee6c21c58f4c6
+        .quad   0x97ac397660e668ea
+        .quad   0x9b19bbfe153ab497
+        .quad   0x4cb179b534eca79f
+        .quad   0x6151c09fa131ae57
+        .quad   0x3af55c0dfdf05d96
+        .quad   0xdd262ee02ab4ee7a
+        .quad   0x11b2bb8712171709
+        .quad   0x1fef24fa800f030b
+
+        // 2^84 * 1 * G
+
+        .quad   0xb496123a6b6c6609
+        .quad   0xa750fe8580ab5938
+        .quad   0xf471bf39b7c27a5f
+        .quad   0x507903ce77ac193c
+        .quad   0xff91a66a90166220
+        .quad   0xf22552ae5bf1e009
+        .quad   0x7dff85d87f90df7c
+        .quad   0x4f620ffe0c736fb9
+        .quad   0x62f90d65dfde3e34
+        .quad   0xcf28c592b9fa5fad
+        .quad   0x99c86ef9c6164510
+        .quad   0x25d448044a256c84
+
+        // 2^84 * 2 * G
+
+        .quad   0xbd68230ec7e9b16f
+        .quad   0x0eb1b9c1c1c5795d
+        .quad   0x7943c8c495b6b1ff
+        .quad   0x2f9faf620bbacf5e
+        .quad   0x2c7c4415c9022b55
+        .quad   0x56a0d241812eb1fe
+        .quad   0xf02ea1c9d7b65e0d
+        .quad   0x4180512fd5323b26
+        .quad   0xa4ff3e698a48a5db
+        .quad   0xba6a3806bd95403b
+        .quad   0x9f7ce1af47d5b65d
+        .quad   0x15e087e55939d2fb
+
+        // 2^84 * 3 * G
+
+        .quad   0x12207543745c1496
+        .quad   0xdaff3cfdda38610c
+        .quad   0xe4e797272c71c34f
+        .quad   0x39c07b1934bdede9
+        .quad   0x8894186efb963f38
+        .quad   0x48a00e80dc639bd5
+        .quad   0xa4e8092be96c1c99
+        .quad   0x5a097d54ca573661
+        .quad   0x2d45892b17c9e755
+        .quad   0xd033fd7289308df8
+        .quad   0x6c2fe9d9525b8bd9
+        .quad   0x2edbecf1c11cc079
+
+        // 2^84 * 4 * G
+
+        .quad   0x1616a4e3c715a0d2
+        .quad   0x53623cb0f8341d4d
+        .quad   0x96ef5329c7e899cb
+        .quad   0x3d4e8dbba668baa6
+        .quad   0xee0f0fddd087a25f
+        .quad   0x9c7531555c3e34ee
+        .quad   0x660c572e8fab3ab5
+        .quad   0x0854fc44544cd3b2
+        .quad   0x61eba0c555edad19
+        .quad   0x24b533fef0a83de6
+        .quad   0x3b77042883baa5f8
+        .quad   0x678f82b898a47e8d
+
+        // 2^84 * 5 * G
+
+        .quad   0xb1491d0bd6900c54
+        .quad   0x3539722c9d132636
+        .quad   0x4db928920b362bc9
+        .quad   0x4d7cd1fea68b69df
+        .quad   0x1e09d94057775696
+        .quad   0xeed1265c3cd951db
+        .quad   0xfa9dac2b20bce16f
+        .quad   0x0f7f76e0e8d089f4
+        .quad   0x36d9ebc5d485b00c
+        .quad   0xa2596492e4adb365
+        .quad   0xc1659480c2119ccd
+        .quad   0x45306349186e0d5f
+
+        // 2^84 * 6 * G
+
+        .quad   0x94ddd0c1a6cdff1d
+        .quad   0x55f6f115e84213ae
+        .quad   0x6c935f85992fcf6a
+        .quad   0x067ee0f54a37f16f
+        .quad   0x96a414ec2b072491
+        .quad   0x1bb2218127a7b65b
+        .quad   0x6d2849596e8a4af0
+        .quad   0x65f3b08ccd27765f
+        .quad   0xecb29fff199801f7
+        .quad   0x9d361d1fa2a0f72f
+        .quad   0x25f11d2375fd2f49
+        .quad   0x124cefe80fe10fe2
+
+        // 2^84 * 7 * G
+
+        .quad   0x4c126cf9d18df255
+        .quad   0xc1d471e9147a63b6
+        .quad   0x2c6d3c73f3c93b5f
+        .quad   0x6be3a6a2e3ff86a2
+        .quad   0x1518e85b31b16489
+        .quad   0x8faadcb7db710bfb
+        .quad   0x39b0bdf4a14ae239
+        .quad   0x05f4cbea503d20c1
+        .quad   0xce040e9ec04145bc
+        .quad   0xc71ff4e208f6834c
+        .quad   0xbd546e8dab8847a3
+        .quad   0x64666aa0a4d2aba5
+
+        // 2^84 * 8 * G
+
+        .quad   0x6841435a7c06d912
+        .quad   0xca123c21bb3f830b
+        .quad   0xd4b37b27b1cbe278
+        .quad   0x1d753b84c76f5046
+        .quad   0xb0c53bf73337e94c
+        .quad   0x7cb5697e11e14f15
+        .quad   0x4b84abac1930c750
+        .quad   0x28dd4abfe0640468
+        .quad   0x7dc0b64c44cb9f44
+        .quad   0x18a3e1ace3925dbf
+        .quad   0x7a3034862d0457c4
+        .quad   0x4c498bf78a0c892e
+
+        // 2^88 * 1 * G
+
+        .quad   0x37d653fb1aa73196
+        .quad   0x0f9495303fd76418
+        .quad   0xad200b09fb3a17b2
+        .quad   0x544d49292fc8613e
+        .quad   0x22d2aff530976b86
+        .quad   0x8d90b806c2d24604
+        .quad   0xdca1896c4de5bae5
+        .quad   0x28005fe6c8340c17
+        .quad   0x6aefba9f34528688
+        .quad   0x5c1bff9425107da1
+        .quad   0xf75bbbcd66d94b36
+        .quad   0x72e472930f316dfa
+
+        // 2^88 * 2 * G
+
+        .quad   0x2695208c9781084f
+        .quad   0xb1502a0b23450ee1
+        .quad   0xfd9daea603efde02
+        .quad   0x5a9d2e8c2733a34c
+        .quad   0x07f3f635d32a7627
+        .quad   0x7aaa4d865f6566f0
+        .quad   0x3c85e79728d04450
+        .quad   0x1fee7f000fe06438
+        .quad   0x765305da03dbf7e5
+        .quad   0xa4daf2491434cdbd
+        .quad   0x7b4ad5cdd24a88ec
+        .quad   0x00f94051ee040543
+
+        // 2^88 * 3 * G
+
+        .quad   0x8d356b23c3d330b2
+        .quad   0xf21c8b9bb0471b06
+        .quad   0xb36c316c6e42b83c
+        .quad   0x07d79c7e8beab10d
+        .quad   0xd7ef93bb07af9753
+        .quad   0x583ed0cf3db766a7
+        .quad   0xce6998bf6e0b1ec5
+        .quad   0x47b7ffd25dd40452
+        .quad   0x87fbfb9cbc08dd12
+        .quad   0x8a066b3ae1eec29b
+        .quad   0x0d57242bdb1fc1bf
+        .quad   0x1c3520a35ea64bb6
+
+        // 2^88 * 4 * G
+
+        .quad   0x80d253a6bccba34a
+        .quad   0x3e61c3a13838219b
+        .quad   0x90c3b6019882e396
+        .quad   0x1c3d05775d0ee66f
+        .quad   0xcda86f40216bc059
+        .quad   0x1fbb231d12bcd87e
+        .quad   0xb4956a9e17c70990
+        .quad   0x38750c3b66d12e55
+        .quad   0x692ef1409422e51a
+        .quad   0xcbc0c73c2b5df671
+        .quad   0x21014fe7744ce029
+        .quad   0x0621e2c7d330487c
+
+        // 2^88 * 5 * G
+
+        .quad   0xaf9860cc8259838d
+        .quad   0x90ea48c1c69f9adc
+        .quad   0x6526483765581e30
+        .quad   0x0007d6097bd3a5bc
+        .quad   0xb7ae1796b0dbf0f3
+        .quad   0x54dfafb9e17ce196
+        .quad   0x25923071e9aaa3b4
+        .quad   0x5d8e589ca1002e9d
+        .quad   0xc0bf1d950842a94b
+        .quad   0xb2d3c363588f2e3e
+        .quad   0x0a961438bb51e2ef
+        .quad   0x1583d7783c1cbf86
+
+        // 2^88 * 6 * G
+
+        .quad   0xeceea2ef5da27ae1
+        .quad   0x597c3a1455670174
+        .quad   0xc9a62a126609167a
+        .quad   0x252a5f2e81ed8f70
+        .quad   0x90034704cc9d28c7
+        .quad   0x1d1b679ef72cc58f
+        .quad   0x16e12b5fbe5b8726
+        .quad   0x4958064e83c5580a
+        .quad   0x0d2894265066e80d
+        .quad   0xfcc3f785307c8c6b
+        .quad   0x1b53da780c1112fd
+        .quad   0x079c170bd843b388
+
+        // 2^88 * 7 * G
+
+        .quad   0x0506ece464fa6fff
+        .quad   0xbee3431e6205e523
+        .quad   0x3579422451b8ea42
+        .quad   0x6dec05e34ac9fb00
+        .quad   0xcdd6cd50c0d5d056
+        .quad   0x9af7686dbb03573b
+        .quad   0x3ca6723ff3c3ef48
+        .quad   0x6768c0d7317b8acc
+        .quad   0x94b625e5f155c1b3
+        .quad   0x417bf3a7997b7b91
+        .quad   0xc22cbddc6d6b2600
+        .quad   0x51445e14ddcd52f4
+
+        // 2^88 * 8 * G
+
+        .quad   0x57502b4b3b144951
+        .quad   0x8e67ff6b444bbcb3
+        .quad   0xb8bd6927166385db
+        .quad   0x13186f31e39295c8
+        .quad   0x893147ab2bbea455
+        .quad   0x8c53a24f92079129
+        .quad   0x4b49f948be30f7a7
+        .quad   0x12e990086e4fd43d
+        .quad   0xf10c96b37fdfbb2e
+        .quad   0x9f9a935e121ceaf9
+        .quad   0xdf1136c43a5b983f
+        .quad   0x77b2e3f05d3e99af
+
+        // 2^92 * 1 * G
+
+        .quad   0xfd0d75879cf12657
+        .quad   0xe82fef94e53a0e29
+        .quad   0xcc34a7f05bbb4be7
+        .quad   0x0b251172a50c38a2
+        .quad   0x9532f48fcc5cd29b
+        .quad   0x2ba851bea3ce3671
+        .quad   0x32dacaa051122941
+        .quad   0x478d99d9350004f2
+        .quad   0x1d5ad94890bb02c0
+        .quad   0x50e208b10ec25115
+        .quad   0xa26a22894ef21702
+        .quad   0x4dc923343b524805
+
+        // 2^92 * 2 * G
+
+        .quad   0xe3828c400f8086b6
+        .quad   0x3f77e6f7979f0dc8
+        .quad   0x7ef6de304df42cb4
+        .quad   0x5265797cb6abd784
+        .quad   0x3ad3e3ebf36c4975
+        .quad   0xd75d25a537862125
+        .quad   0xe873943da025a516
+        .quad   0x6bbc7cb4c411c847
+        .quad   0x3c6f9cd1d4a50d56
+        .quad   0xb6244077c6feab7e
+        .quad   0x6ff9bf483580972e
+        .quad   0x00375883b332acfb
+
+        // 2^92 * 3 * G
+
+        .quad   0x0001b2cd28cb0940
+        .quad   0x63fb51a06f1c24c9
+        .quad   0xb5ad8691dcd5ca31
+        .quad   0x67238dbd8c450660
+        .quad   0xc98bec856c75c99c
+        .quad   0xe44184c000e33cf4
+        .quad   0x0a676b9bba907634
+        .quad   0x669e2cb571f379d7
+        .quad   0xcb116b73a49bd308
+        .quad   0x025aad6b2392729e
+        .quad   0xb4793efa3f55d9b1
+        .quad   0x72a1056140678bb9
+
+        // 2^92 * 4 * G
+
+        .quad   0xa2b6812b1cc9249d
+        .quad   0x62866eee21211f58
+        .quad   0x2cb5c5b85df10ece
+        .quad   0x03a6b259e263ae00
+        .quad   0x0d8d2909e2e505b6
+        .quad   0x98ca78abc0291230
+        .quad   0x77ef5569a9b12327
+        .quad   0x7c77897b81439b47
+        .quad   0xf1c1b5e2de331cb5
+        .quad   0x5a9f5d8e15fca420
+        .quad   0x9fa438f17bd932b1
+        .quad   0x2a381bf01c6146e7
+
+        // 2^92 * 5 * G
+
+        .quad   0xac9b9879cfc811c1
+        .quad   0x8b7d29813756e567
+        .quad   0x50da4e607c70edfc
+        .quad   0x5dbca62f884400b6
+        .quad   0xf7c0be32b534166f
+        .quad   0x27e6ca6419cf70d4
+        .quad   0x934df7d7a957a759
+        .quad   0x5701461dabdec2aa
+        .quad   0x2c6747402c915c25
+        .quad   0x1bdcd1a80b0d340a
+        .quad   0x5e5601bd07b43f5f
+        .quad   0x2555b4e05539a242
+
+        // 2^92 * 6 * G
+
+        .quad   0x6fc09f5266ddd216
+        .quad   0xdce560a7c8e37048
+        .quad   0xec65939da2df62fd
+        .quad   0x7a869ae7e52ed192
+        .quad   0x78409b1d87e463d4
+        .quad   0xad4da95acdfb639d
+        .quad   0xec28773755259b9c
+        .quad   0x69c806e9c31230ab
+        .quad   0x7b48f57414bb3f22
+        .quad   0x68c7cee4aedccc88
+        .quad   0xed2f936179ed80be
+        .quad   0x25d70b885f77bc4b
+
+        // 2^92 * 7 * G
+
+        .quad   0x4151c3d9762bf4de
+        .quad   0x083f435f2745d82b
+        .quad   0x29775a2e0d23ddd5
+        .quad   0x138e3a6269a5db24
+        .quad   0x98459d29bb1ae4d4
+        .quad   0x56b9c4c739f954ec
+        .quad   0x832743f6c29b4b3e
+        .quad   0x21ea8e2798b6878a
+        .quad   0x87bef4b46a5a7b9c
+        .quad   0xd2299d1b5fc1d062
+        .quad   0x82409818dd321648
+        .quad   0x5c5abeb1e5a2e03d
+
+        // 2^92 * 8 * G
+
+        .quad   0x14722af4b73c2ddb
+        .quad   0xbc470c5f5a05060d
+        .quad   0x00943eac2581b02e
+        .quad   0x0e434b3b1f499c8f
+        .quad   0x02cde6de1306a233
+        .quad   0x7b5a52a2116f8ec7
+        .quad   0xe1c681f4c1163b5b
+        .quad   0x241d350660d32643
+        .quad   0x6be4404d0ebc52c7
+        .quad   0xae46233bb1a791f5
+        .quad   0x2aec170ed25db42b
+        .quad   0x1d8dfd966645d694
+
+        // 2^96 * 1 * G
+
+        .quad   0x296fa9c59c2ec4de
+        .quad   0xbc8b61bf4f84f3cb
+        .quad   0x1c7706d917a8f908
+        .quad   0x63b795fc7ad3255d
+        .quad   0xd598639c12ddb0a4
+        .quad   0xa5d19f30c024866b
+        .quad   0xd17c2f0358fce460
+        .quad   0x07a195152e095e8a
+        .quad   0xa8368f02389e5fc8
+        .quad   0x90433b02cf8de43b
+        .quad   0xafa1fd5dc5412643
+        .quad   0x3e8fe83d032f0137
+
+        // 2^96 * 2 * G
+
+        .quad   0x2f8b15b90570a294
+        .quad   0x94f2427067084549
+        .quad   0xde1c5ae161bbfd84
+        .quad   0x75ba3b797fac4007
+        .quad   0x08704c8de8efd13c
+        .quad   0xdfc51a8e33e03731
+        .quad   0xa59d5da51260cde3
+        .quad   0x22d60899a6258c86
+        .quad   0x6239dbc070cdd196
+        .quad   0x60fe8a8b6c7d8a9a
+        .quad   0xb38847bceb401260
+        .quad   0x0904d07b87779e5e
+
+        // 2^96 * 3 * G
+
+        .quad   0xb4ce1fd4ddba919c
+        .quad   0xcf31db3ec74c8daa
+        .quad   0x2c63cc63ad86cc51
+        .quad   0x43e2143fbc1dde07
+        .quad   0xf4322d6648f940b9
+        .quad   0x06952f0cbd2d0c39
+        .quad   0x167697ada081f931
+        .quad   0x6240aacebaf72a6c
+        .quad   0xf834749c5ba295a0
+        .quad   0xd6947c5bca37d25a
+        .quad   0x66f13ba7e7c9316a
+        .quad   0x56bdaf238db40cac
+
+        // 2^96 * 4 * G
+
+        .quad   0x362ab9e3f53533eb
+        .quad   0x338568d56eb93d40
+        .quad   0x9e0e14521d5a5572
+        .quad   0x1d24a86d83741318
+        .quad   0x1310d36cc19d3bb2
+        .quad   0x062a6bb7622386b9
+        .quad   0x7c9b8591d7a14f5c
+        .quad   0x03aa31507e1e5754
+        .quad   0xf4ec7648ffd4ce1f
+        .quad   0xe045eaf054ac8c1c
+        .quad   0x88d225821d09357c
+        .quad   0x43b261dc9aeb4859
+
+        // 2^96 * 5 * G
+
+        .quad   0xe55b1e1988bb79bb
+        .quad   0xa09ed07dc17a359d
+        .quad   0xb02c2ee2603dea33
+        .quad   0x326055cf5b276bc2
+        .quad   0x19513d8b6c951364
+        .quad   0x94fe7126000bf47b
+        .quad   0x028d10ddd54f9567
+        .quad   0x02b4d5e242940964
+        .quad   0xb4a155cb28d18df2
+        .quad   0xeacc4646186ce508
+        .quad   0xc49cf4936c824389
+        .quad   0x27a6c809ae5d3410
+
+        // 2^96 * 6 * G
+
+        .quad   0x8ba6ebcd1f0db188
+        .quad   0x37d3d73a675a5be8
+        .quad   0xf22edfa315f5585a
+        .quad   0x2cb67174ff60a17e
+        .quad   0xcd2c270ac43d6954
+        .quad   0xdd4a3e576a66cab2
+        .quad   0x79fa592469d7036c
+        .quad   0x221503603d8c2599
+        .quad   0x59eecdf9390be1d0
+        .quad   0xa9422044728ce3f1
+        .quad   0x82891c667a94f0f4
+        .quad   0x7b1df4b73890f436
+
+        // 2^96 * 7 * G
+
+        .quad   0xe492f2e0b3b2a224
+        .quad   0x7c6c9e062b551160
+        .quad   0x15eb8fe20d7f7b0e
+        .quad   0x61fcef2658fc5992
+        .quad   0x5f2e221807f8f58c
+        .quad   0xe3555c9fd49409d4
+        .quad   0xb2aaa88d1fb6a630
+        .quad   0x68698245d352e03d
+        .quad   0xdbb15d852a18187a
+        .quad   0xf3e4aad386ddacd7
+        .quad   0x44bae2810ff6c482
+        .quad   0x46cf4c473daf01cf
+
+        // 2^96 * 8 * G
+
+        .quad   0x426525ed9ec4e5f9
+        .quad   0x0e5eda0116903303
+        .quad   0x72b1a7f2cbe5cadc
+        .quad   0x29387bcd14eb5f40
+        .quad   0x213c6ea7f1498140
+        .quad   0x7c1e7ef8392b4854
+        .quad   0x2488c38c5629ceba
+        .quad   0x1065aae50d8cc5bb
+        .quad   0x1c2c4525df200d57
+        .quad   0x5c3b2dd6bfca674a
+        .quad   0x0a07e7b1e1834030
+        .quad   0x69a198e64f1ce716
+
+        // 2^100 * 1 * G
+
+        .quad   0x7afcd613efa9d697
+        .quad   0x0cc45aa41c067959
+        .quad   0xa56fe104c1fada96
+        .quad   0x3a73b70472e40365
+        .quad   0x7b26e56b9e2d4734
+        .quad   0xc4c7132b81c61675
+        .quad   0xef5c9525ec9cde7f
+        .quad   0x39c80b16e71743ad
+        .quad   0x0f196e0d1b826c68
+        .quad   0xf71ff0e24960e3db
+        .quad   0x6113167023b7436c
+        .quad   0x0cf0ea5877da7282
+
+        // 2^100 * 2 * G
+
+        .quad   0x196c80a4ddd4ccbd
+        .quad   0x22e6f55d95f2dd9d
+        .quad   0xc75e33c740d6c71b
+        .quad   0x7bb51279cb3c042f
+        .quad   0xe332ced43ba6945a
+        .quad   0xde0b1361e881c05d
+        .quad   0x1ad40f095e67ed3b
+        .quad   0x5da8acdab8c63d5d
+        .quad   0xc4b6664a3a70159f
+        .quad   0x76194f0f0a904e14
+        .quad   0xa5614c39a4096c13
+        .quad   0x6cd0ff50979feced
+
+        // 2^100 * 3 * G
+
+        .quad   0xc0e067e78f4428ac
+        .quad   0x14835ab0a61135e3
+        .quad   0xf21d14f338062935
+        .quad   0x6390a4c8df04849c
+        .quad   0x7fecfabdb04ba18e
+        .quad   0xd0fc7bfc3bddbcf7
+        .quad   0xa41d486e057a131c
+        .quad   0x641a4391f2223a61
+        .quad   0xc5c6b95aa606a8db
+        .quad   0x914b7f9eb06825f1
+        .quad   0x2a731f6b44fc9eff
+        .quad   0x30ddf38562705cfc
+
+        // 2^100 * 4 * G
+
+        .quad   0x4e3dcbdad1bff7f9
+        .quad   0xc9118e8220645717
+        .quad   0xbacccebc0f189d56
+        .quad   0x1b4822e9d4467668
+        .quad   0x33bef2bd68bcd52c
+        .quad   0xc649dbb069482ef2
+        .quad   0xb5b6ee0c41cb1aee
+        .quad   0x5c294d270212a7e5
+        .quad   0xab360a7f25563781
+        .quad   0x2512228a480f7958
+        .quad   0xc75d05276114b4e3
+        .quad   0x222d9625d976fe2a
+
+        // 2^100 * 5 * G
+
+        .quad   0x1c717f85b372ace1
+        .quad   0x81930e694638bf18
+        .quad   0x239cad056bc08b58
+        .quad   0x0b34271c87f8fff4
+        .quad   0x0f94be7e0a344f85
+        .quad   0xeb2faa8c87f22c38
+        .quad   0x9ce1e75e4ee16f0f
+        .quad   0x43e64e5418a08dea
+        .quad   0x8155e2521a35ce63
+        .quad   0xbe100d4df912028e
+        .quad   0xbff80bf8a57ddcec
+        .quad   0x57342dc96d6bc6e4
+
+        // 2^100 * 6 * G
+
+        .quad   0xefeef065c8ce5998
+        .quad   0xbf029510b5cbeaa2
+        .quad   0x8c64a10620b7c458
+        .quad   0x35134fb231c24855
+        .quad   0xf3c3bcb71e707bf6
+        .quad   0x351d9b8c7291a762
+        .quad   0x00502e6edad69a33
+        .quad   0x522f521f1ec8807f
+        .quad   0x272c1f46f9a3902b
+        .quad   0xc91ba3b799657bcc
+        .quad   0xae614b304f8a1c0e
+        .quad   0x7afcaad70b99017b
+
+        // 2^100 * 7 * G
+
+        .quad   0xc25ded54a4b8be41
+        .quad   0x902d13e11bb0e2dd
+        .quad   0x41f43233cde82ab2
+        .quad   0x1085faa5c3aae7cb
+        .quad   0xa88141ecef842b6b
+        .quad   0x55e7b14797abe6c5
+        .quad   0x8c748f9703784ffe
+        .quad   0x5b50a1f7afcd00b7
+        .quad   0x9b840f66f1361315
+        .quad   0x18462242701003e9
+        .quad   0x65ed45fae4a25080
+        .quad   0x0a2862393fda7320
+
+        // 2^100 * 8 * G
+
+        .quad   0x46ab13c8347cbc9d
+        .quad   0x3849e8d499c12383
+        .quad   0x4cea314087d64ac9
+        .quad   0x1f354134b1a29ee7
+        .quad   0x960e737b6ecb9d17
+        .quad   0xfaf24948d67ceae1
+        .quad   0x37e7a9b4d55e1b89
+        .quad   0x5cb7173cb46c59eb
+        .quad   0x4a89e68b82b7abf0
+        .quad   0xf41cd9279ba6b7b9
+        .quad   0x16e6c210e18d876f
+        .quad   0x7cacdb0f7f1b09c6
+
+        // 2^104 * 1 * G
+
+        .quad   0x9062b2e0d91a78bc
+        .quad   0x47c9889cc8509667
+        .quad   0x9df54a66405070b8
+        .quad   0x7369e6a92493a1bf
+        .quad   0xe1014434dcc5caed
+        .quad   0x47ed5d963c84fb33
+        .quad   0x70019576ed86a0e7
+        .quad   0x25b2697bd267f9e4
+        .quad   0x9d673ffb13986864
+        .quad   0x3ca5fbd9415dc7b8
+        .quad   0xe04ecc3bdf273b5e
+        .quad   0x1420683db54e4cd2
+
+        // 2^104 * 2 * G
+
+        .quad   0xb478bd1e249dd197
+        .quad   0x620c35005e58c102
+        .quad   0xfb02d32fccbaac5c
+        .quad   0x60b63bebf508a72d
+        .quad   0x34eebb6fc1cc5ad0
+        .quad   0x6a1b0ce99646ac8b
+        .quad   0xd3b0da49a66bde53
+        .quad   0x31e83b4161d081c1
+        .quad   0x97e8c7129e062b4f
+        .quad   0x49e48f4f29320ad8
+        .quad   0x5bece14b6f18683f
+        .quad   0x55cf1eb62d550317
+
+        // 2^104 * 3 * G
+
+        .quad   0x5879101065c23d58
+        .quad   0x8b9d086d5094819c
+        .quad   0xe2402fa912c55fa7
+        .quad   0x669a6564570891d4
+        .quad   0x3076b5e37df58c52
+        .quad   0xd73ab9dde799cc36
+        .quad   0xbd831ce34913ee20
+        .quad   0x1a56fbaa62ba0133
+        .quad   0x943e6b505c9dc9ec
+        .quad   0x302557bba77c371a
+        .quad   0x9873ae5641347651
+        .quad   0x13c4836799c58a5c
+
+        // 2^104 * 4 * G
+
+        .quad   0x423a5d465ab3e1b9
+        .quad   0xfc13c187c7f13f61
+        .quad   0x19f83664ecb5b9b6
+        .quad   0x66f80c93a637b607
+        .quad   0xc4dcfb6a5d8bd080
+        .quad   0xdeebc4ec571a4842
+        .quad   0xd4b2e883b8e55365
+        .quad   0x50bdc87dc8e5b827
+        .quad   0x606d37836edfe111
+        .quad   0x32353e15f011abd9
+        .quad   0x64b03ac325b73b96
+        .quad   0x1dd56444725fd5ae
+
+        // 2^104 * 5 * G
+
+        .quad   0x8fa47ff83362127d
+        .quad   0xbc9f6ac471cd7c15
+        .quad   0x6e71454349220c8b
+        .quad   0x0e645912219f732e
+        .quad   0xc297e60008bac89a
+        .quad   0x7d4cea11eae1c3e0
+        .quad   0xf3e38be19fe7977c
+        .quad   0x3a3a450f63a305cd
+        .quad   0x078f2f31d8394627
+        .quad   0x389d3183de94a510
+        .quad   0xd1e36c6d17996f80
+        .quad   0x318c8d9393a9a87b
+
+        // 2^104 * 6 * G
+
+        .quad   0xf2745d032afffe19
+        .quad   0x0c9f3c497f24db66
+        .quad   0xbc98d3e3ba8598ef
+        .quad   0x224c7c679a1d5314
+        .quad   0x5d669e29ab1dd398
+        .quad   0xfc921658342d9e3b
+        .quad   0x55851dfdf35973cd
+        .quad   0x509a41c325950af6
+        .quad   0xbdc06edca6f925e9
+        .quad   0x793ef3f4641b1f33
+        .quad   0x82ec12809d833e89
+        .quad   0x05bff02328a11389
+
+        // 2^104 * 7 * G
+
+        .quad   0x3632137023cae00b
+        .quad   0x544acf0ad1accf59
+        .quad   0x96741049d21a1c88
+        .quad   0x780b8cc3fa2a44a7
+        .quad   0x6881a0dd0dc512e4
+        .quad   0x4fe70dc844a5fafe
+        .quad   0x1f748e6b8f4a5240
+        .quad   0x576277cdee01a3ea
+        .quad   0x1ef38abc234f305f
+        .quad   0x9a577fbd1405de08
+        .quad   0x5e82a51434e62a0d
+        .quad   0x5ff418726271b7a1
+
+        // 2^104 * 8 * G
+
+        .quad   0x398e080c1789db9d
+        .quad   0xa7602025f3e778f5
+        .quad   0xfa98894c06bd035d
+        .quad   0x106a03dc25a966be
+        .quad   0xe5db47e813b69540
+        .quad   0xf35d2a3b432610e1
+        .quad   0xac1f26e938781276
+        .quad   0x29d4db8ca0a0cb69
+        .quad   0xd9ad0aaf333353d0
+        .quad   0x38669da5acd309e5
+        .quad   0x3c57658ac888f7f0
+        .quad   0x4ab38a51052cbefa
+
+        // 2^108 * 1 * G
+
+        .quad   0xdfdacbee4324c0e9
+        .quad   0x054442883f955bb7
+        .quad   0xdef7aaa8ea31609f
+        .quad   0x68aee70642287cff
+        .quad   0xf68fe2e8809de054
+        .quad   0xe3bc096a9c82bad1
+        .quad   0x076353d40aadbf45
+        .quad   0x7b9b1fb5dea1959e
+        .quad   0xf01cc8f17471cc0c
+        .quad   0x95242e37579082bb
+        .quad   0x27776093d3e46b5f
+        .quad   0x2d13d55a28bd85fb
+
+        // 2^108 * 2 * G
+
+        .quad   0xfac5d2065b35b8da
+        .quad   0xa8da8a9a85624bb7
+        .quad   0xccd2ca913d21cd0f
+        .quad   0x6b8341ee8bf90d58
+        .quad   0xbf019cce7aee7a52
+        .quad   0xa8ded2b6e454ead3
+        .quad   0x3c619f0b87a8bb19
+        .quad   0x3619b5d7560916d8
+        .quad   0x3579f26b0282c4b2
+        .quad   0x64d592f24fafefae
+        .quad   0xb7cded7b28c8c7c0
+        .quad   0x6a927b6b7173a8d7
+
+        // 2^108 * 3 * G
+
+        .quad   0x1f6db24f986e4656
+        .quad   0x1021c02ed1e9105b
+        .quad   0xf8ff3fff2cc0a375
+        .quad   0x1d2a6bf8c6c82592
+        .quad   0x8d7040863ece88eb
+        .quad   0xf0e307a980eec08c
+        .quad   0xac2250610d788fda
+        .quad   0x056d92a43a0d478d
+        .quad   0x1b05a196fc3da5a1
+        .quad   0x77d7a8c243b59ed0
+        .quad   0x06da3d6297d17918
+        .quad   0x66fbb494f12353f7
+
+        // 2^108 * 4 * G
+
+        .quad   0x751a50b9d85c0fb8
+        .quad   0xd1afdc258bcf097b
+        .quad   0x2f16a6a38309a969
+        .quad   0x14ddff9ee5b00659
+        .quad   0xd6d70996f12309d6
+        .quad   0xdbfb2385e9c3d539
+        .quad   0x46d602b0f7552411
+        .quad   0x270a0b0557843e0c
+        .quad   0x61ff0640a7862bcc
+        .quad   0x81cac09a5f11abfe
+        .quad   0x9047830455d12abb
+        .quad   0x19a4bde1945ae873
+
+        // 2^108 * 5 * G
+
+        .quad   0x9b9f26f520a6200a
+        .quad   0x64804443cf13eaf8
+        .quad   0x8a63673f8631edd3
+        .quad   0x72bbbce11ed39dc1
+        .quad   0x40c709dec076c49f
+        .quad   0x657bfaf27f3e53f6
+        .quad   0x40662331eca042c4
+        .quad   0x14b375487eb4df04
+        .quad   0xae853c94ab66dc47
+        .quad   0xeb62343edf762d6e
+        .quad   0xf08e0e186fb2f7d1
+        .quad   0x4f0b1c02700ab37a
+
+        // 2^108 * 6 * G
+
+        .quad   0xe1706787d81951fa
+        .quad   0xa10a2c8eb290c77b
+        .quad   0xe7382fa03ed66773
+        .quad   0x0a4d84710bcc4b54
+        .quad   0x79fd21ccc1b2e23f
+        .quad   0x4ae7c281453df52a
+        .quad   0xc8172ec9d151486b
+        .quad   0x68abe9443e0a7534
+        .quad   0xda12c6c407831dcb
+        .quad   0x0da230d74d5c510d
+        .quad   0x4ab1531e6bd404e1
+        .quad   0x4106b166bcf440ef
+
+        // 2^108 * 7 * G
+
+        .quad   0x02e57a421cd23668
+        .quad   0x4ad9fb5d0eaef6fd
+        .quad   0x954e6727b1244480
+        .quad   0x7f792f9d2699f331
+        .quad   0xa485ccd539e4ecf2
+        .quad   0x5aa3f3ad0555bab5
+        .quad   0x145e3439937df82d
+        .quad   0x1238b51e1214283f
+        .quad   0x0b886b925fd4d924
+        .quad   0x60906f7a3626a80d
+        .quad   0xecd367b4b98abd12
+        .quad   0x2876beb1def344cf
+
+        // 2^108 * 8 * G
+
+        .quad   0xdc84e93563144691
+        .quad   0x632fe8a0d61f23f4
+        .quad   0x4caa800612a9a8d5
+        .quad   0x48f9dbfa0e9918d3
+        .quad   0xd594b3333a8a85f8
+        .quad   0x4ea37689e78d7d58
+        .quad   0x73bf9f455e8e351f
+        .quad   0x5507d7d2bc41ebb4
+        .quad   0x1ceb2903299572fc
+        .quad   0x7c8ccaa29502d0ee
+        .quad   0x91bfa43411cce67b
+        .quad   0x5784481964a831e7
+
+        // 2^112 * 1 * G
+
+        .quad   0xda7c2b256768d593
+        .quad   0x98c1c0574422ca13
+        .quad   0xf1a80bd5ca0ace1d
+        .quad   0x29cdd1adc088a690
+        .quad   0xd6cfd1ef5fddc09c
+        .quad   0xe82b3efdf7575dce
+        .quad   0x25d56b5d201634c2
+        .quad   0x3041c6bb04ed2b9b
+        .quad   0x0ff2f2f9d956e148
+        .quad   0xade797759f356b2e
+        .quad   0x1a4698bb5f6c025c
+        .quad   0x104bbd6814049a7b
+
+        // 2^112 * 2 * G
+
+        .quad   0x51f0fd3168f1ed67
+        .quad   0x2c811dcdd86f3bc2
+        .quad   0x44dc5c4304d2f2de
+        .quad   0x5be8cc57092a7149
+        .quad   0xa95d9a5fd67ff163
+        .quad   0xe92be69d4cc75681
+        .quad   0xb7f8024cde20f257
+        .quad   0x204f2a20fb072df5
+        .quad   0xc8143b3d30ebb079
+        .quad   0x7589155abd652e30
+        .quad   0x653c3c318f6d5c31
+        .quad   0x2570fb17c279161f
+
+        // 2^112 * 3 * G
+
+        .quad   0x3efa367f2cb61575
+        .quad   0xf5f96f761cd6026c
+        .quad   0xe8c7142a65b52562
+        .quad   0x3dcb65ea53030acd
+        .quad   0x192ea9550bb8245a
+        .quad   0xc8e6fba88f9050d1
+        .quad   0x7986ea2d88a4c935
+        .quad   0x241c5f91de018668
+        .quad   0x28d8172940de6caa
+        .quad   0x8fbf2cf022d9733a
+        .quad   0x16d7fcdd235b01d1
+        .quad   0x08420edd5fcdf0e5
+
+        // 2^112 * 4 * G
+
+        .quad   0xcdff20ab8362fa4a
+        .quad   0x57e118d4e21a3e6e
+        .quad   0xe3179617fc39e62b
+        .quad   0x0d9a53efbc1769fd
+        .quad   0x0358c34e04f410ce
+        .quad   0xb6135b5a276e0685
+        .quad   0x5d9670c7ebb91521
+        .quad   0x04d654f321db889c
+        .quad   0x5e7dc116ddbdb5d5
+        .quad   0x2954deb68da5dd2d
+        .quad   0x1cb608173334a292
+        .quad   0x4a7a4f2618991ad7
+
+        // 2^112 * 5 * G
+
+        .quad   0xf4a718025fb15f95
+        .quad   0x3df65f346b5c1b8f
+        .quad   0xcdfcf08500e01112
+        .quad   0x11b50c4cddd31848
+        .quad   0x24c3b291af372a4b
+        .quad   0x93da8270718147f2
+        .quad   0xdd84856486899ef2
+        .quad   0x4a96314223e0ee33
+        .quad   0xa6e8274408a4ffd6
+        .quad   0x738e177e9c1576d9
+        .quad   0x773348b63d02b3f2
+        .quad   0x4f4bce4dce6bcc51
+
+        // 2^112 * 6 * G
+
+        .quad   0xa71fce5ae2242584
+        .quad   0x26ea725692f58a9e
+        .quad   0xd21a09d71cea3cf4
+        .quad   0x73fcdd14b71c01e6
+        .quad   0x30e2616ec49d0b6f
+        .quad   0xe456718fcaec2317
+        .quad   0x48eb409bf26b4fa6
+        .quad   0x3042cee561595f37
+        .quad   0x427e7079449bac41
+        .quad   0x855ae36dbce2310a
+        .quad   0x4cae76215f841a7c
+        .quad   0x389e740c9a9ce1d6
+
+        // 2^112 * 7 * G
+
+        .quad   0x64fcb3ae34dcb9ce
+        .quad   0x97500323e348d0ad
+        .quad   0x45b3f07d62c6381b
+        .quad   0x61545379465a6788
+        .quad   0xc9bd78f6570eac28
+        .quad   0xe55b0b3227919ce1
+        .quad   0x65fc3eaba19b91ed
+        .quad   0x25c425e5d6263690
+        .quad   0x3f3e06a6f1d7de6e
+        .quad   0x3ef976278e062308
+        .quad   0x8c14f6264e8a6c77
+        .quad   0x6539a08915484759
+
+        // 2^112 * 8 * G
+
+        .quad   0xe9d21f74c3d2f773
+        .quad   0xc150544125c46845
+        .quad   0x624e5ce8f9b99e33
+        .quad   0x11c5e4aac5cd186c
+        .quad   0xddc4dbd414bb4a19
+        .quad   0x19b2bc3c98424f8e
+        .quad   0x48a89fd736ca7169
+        .quad   0x0f65320ef019bd90
+        .quad   0xd486d1b1cafde0c6
+        .quad   0x4f3fe6e3163b5181
+        .quad   0x59a8af0dfaf2939a
+        .quad   0x4cabc7bdec33072a
+
+        // 2^116 * 1 * G
+
+        .quad   0x16faa8fb532f7428
+        .quad   0xdbd42ea046a4e272
+        .quad   0x5337653b8b9ea480
+        .quad   0x4065947223973f03
+        .quad   0xf7c0a19c1a54a044
+        .quad   0x4a1c5e2477bd9fbb
+        .quad   0xa6e3ca115af22972
+        .quad   0x1819bb953f2e9e0d
+        .quad   0x498fbb795e042e84
+        .quad   0x7d0dd89a7698b714
+        .quad   0x8bfb0ba427fe6295
+        .quad   0x36ba82e721200524
+
+        // 2^116 * 2 * G
+
+        .quad   0xd60ecbb74245ec41
+        .quad   0xfd9be89e34348716
+        .quad   0xc9240afee42284de
+        .quad   0x4472f648d0531db4
+        .quad   0xc8d69d0a57274ed5
+        .quad   0x45ba803260804b17
+        .quad   0xdf3cda102255dfac
+        .quad   0x77d221232709b339
+        .quad   0x498a6d7064ad94d8
+        .quad   0xa5b5c8fd9af62263
+        .quad   0x8ca8ed0545c141f4
+        .quad   0x2c63bec3662d358c
+
+        // 2^116 * 3 * G
+
+        .quad   0x7fe60d8bea787955
+        .quad   0xb9dc117eb5f401b7
+        .quad   0x91c7c09a19355cce
+        .quad   0x22692ef59442bedf
+        .quad   0x9a518b3a8586f8bf
+        .quad   0x9ee71af6cbb196f0
+        .quad   0xaa0625e6a2385cf2
+        .quad   0x1deb2176ddd7c8d1
+        .quad   0x8563d19a2066cf6c
+        .quad   0x401bfd8c4dcc7cd7
+        .quad   0xd976a6becd0d8f62
+        .quad   0x67cfd773a278b05e
+
+        // 2^116 * 4 * G
+
+        .quad   0x8dec31faef3ee475
+        .quad   0x99dbff8a9e22fd92
+        .quad   0x512d11594e26cab1
+        .quad   0x0cde561eec4310b9
+        .quad   0x2d5fa9855a4e586a
+        .quad   0x65f8f7a449beab7e
+        .quad   0xaa074dddf21d33d3
+        .quad   0x185cba721bcb9dee
+        .quad   0x93869da3f4e3cb41
+        .quad   0xbf0392f540f7977e
+        .quad   0x026204fcd0463b83
+        .quad   0x3ec91a769eec6eed
+
+        // 2^116 * 5 * G
+
+        .quad   0x1e9df75bf78166ad
+        .quad   0x4dfda838eb0cd7af
+        .quad   0xba002ed8c1eaf988
+        .quad   0x13fedb3e11f33cfc
+        .quad   0x0fad2fb7b0a3402f
+        .quad   0x46615ecbfb69f4a8
+        .quad   0xf745bcc8c5f8eaa6
+        .quad   0x7a5fa8794a94e896
+        .quad   0x52958faa13cd67a1
+        .quad   0x965ee0818bdbb517
+        .quad   0x16e58daa2e8845b3
+        .quad   0x357d397d5499da8f
+
+        // 2^116 * 6 * G
+
+        .quad   0x1ebfa05fb0bace6c
+        .quad   0xc934620c1caf9a1e
+        .quad   0xcc771cc41d82b61a
+        .quad   0x2d94a16aa5f74fec
+        .quad   0x481dacb4194bfbf8
+        .quad   0x4d77e3f1bae58299
+        .quad   0x1ef4612e7d1372a0
+        .quad   0x3a8d867e70ff69e1
+        .quad   0x6f58cd5d55aff958
+        .quad   0xba3eaa5c75567721
+        .quad   0x75c123999165227d
+        .quad   0x69be1343c2f2b35e
+
+        // 2^116 * 7 * G
+
+        .quad   0x0e091d5ee197c92a
+        .quad   0x4f51019f2945119f
+        .quad   0x143679b9f034e99c
+        .quad   0x7d88112e4d24c696
+        .quad   0x82bbbdac684b8de3
+        .quad   0xa2f4c7d03fca0718
+        .quad   0x337f92fbe096aaa8
+        .quad   0x200d4d8c63587376
+        .quad   0x208aed4b4893b32b
+        .quad   0x3efbf23ebe59b964
+        .quad   0xd762deb0dba5e507
+        .quad   0x69607bd681bd9d94
+
+        // 2^116 * 8 * G
+
+        .quad   0xf6be021068de1ce1
+        .quad   0xe8d518e70edcbc1f
+        .quad   0xe3effdd01b5505a5
+        .quad   0x35f63353d3ec3fd0
+        .quad   0x3b7f3bd49323a902
+        .quad   0x7c21b5566b2c6e53
+        .quad   0xe5ba8ff53a7852a7
+        .quad   0x28bc77a5838ece00
+        .quad   0x63ba78a8e25d8036
+        .quad   0x63651e0094333490
+        .quad   0x48d82f20288ce532
+        .quad   0x3a31abfa36b57524
+
+        // 2^120 * 1 * G
+
+        .quad   0x239e9624089c0a2e
+        .quad   0xc748c4c03afe4738
+        .quad   0x17dbed2a764fa12a
+        .quad   0x639b93f0321c8582
+        .quad   0xc08f788f3f78d289
+        .quad   0xfe30a72ca1404d9f
+        .quad   0xf2778bfccf65cc9d
+        .quad   0x7ee498165acb2021
+        .quad   0x7bd508e39111a1c3
+        .quad   0x2b2b90d480907489
+        .quad   0xe7d2aec2ae72fd19
+        .quad   0x0edf493c85b602a6
+
+        // 2^120 * 2 * G
+
+        .quad   0xaecc8158599b5a68
+        .quad   0xea574f0febade20e
+        .quad   0x4fe41d7422b67f07
+        .quad   0x403b92e3019d4fb4
+        .quad   0x6767c4d284764113
+        .quad   0xa090403ff7f5f835
+        .quad   0x1c8fcffacae6bede
+        .quad   0x04c00c54d1dfa369
+        .quad   0x4dc22f818b465cf8
+        .quad   0x71a0f35a1480eff8
+        .quad   0xaee8bfad04c7d657
+        .quad   0x355bb12ab26176f4
+
+        // 2^120 * 3 * G
+
+        .quad   0xa71e64cc7493bbf4
+        .quad   0xe5bd84d9eca3b0c3
+        .quad   0x0a6bc50cfa05e785
+        .quad   0x0f9b8132182ec312
+        .quad   0xa301dac75a8c7318
+        .quad   0xed90039db3ceaa11
+        .quad   0x6f077cbf3bae3f2d
+        .quad   0x7518eaf8e052ad8e
+        .quad   0xa48859c41b7f6c32
+        .quad   0x0f2d60bcf4383298
+        .quad   0x1815a929c9b1d1d9
+        .quad   0x47c3871bbb1755c4
+
+        // 2^120 * 4 * G
+
+        .quad   0x5144539771ec4f48
+        .quad   0xf805b17dc98c5d6e
+        .quad   0xf762c11a47c3c66b
+        .quad   0x00b89b85764699dc
+        .quad   0xfbe65d50c85066b0
+        .quad   0x62ecc4b0b3a299b0
+        .quad   0xe53754ea441ae8e0
+        .quad   0x08fea02ce8d48d5f
+        .quad   0x824ddd7668deead0
+        .quad   0xc86445204b685d23
+        .quad   0xb514cfcd5d89d665
+        .quad   0x473829a74f75d537
+
+        // 2^120 * 5 * G
+
+        .quad   0x82d2da754679c418
+        .quad   0xe63bd7d8b2618df0
+        .quad   0x355eef24ac47eb0a
+        .quad   0x2078684c4833c6b4
+        .quad   0x23d9533aad3902c9
+        .quad   0x64c2ddceef03588f
+        .quad   0x15257390cfe12fb4
+        .quad   0x6c668b4d44e4d390
+        .quad   0x3b48cf217a78820c
+        .quad   0xf76a0ab281273e97
+        .quad   0xa96c65a78c8eed7b
+        .quad   0x7411a6054f8a433f
+
+        // 2^120 * 6 * G
+
+        .quad   0x4d659d32b99dc86d
+        .quad   0x044cdc75603af115
+        .quad   0xb34c712cdcc2e488
+        .quad   0x7c136574fb8134ff
+        .quad   0x579ae53d18b175b4
+        .quad   0x68713159f392a102
+        .quad   0x8455ecba1eef35f5
+        .quad   0x1ec9a872458c398f
+        .quad   0xb8e6a4d400a2509b
+        .quad   0x9b81d7020bc882b4
+        .quad   0x57e7cc9bf1957561
+        .quad   0x3add88a5c7cd6460
+
+        // 2^120 * 7 * G
+
+        .quad   0xab895770b635dcf2
+        .quad   0x02dfef6cf66c1fbc
+        .quad   0x85530268beb6d187
+        .quad   0x249929fccc879e74
+        .quad   0x85c298d459393046
+        .quad   0x8f7e35985ff659ec
+        .quad   0x1d2ca22af2f66e3a
+        .quad   0x61ba1131a406a720
+        .quad   0xa3d0a0f116959029
+        .quad   0x023b6b6cba7ebd89
+        .quad   0x7bf15a3e26783307
+        .quad   0x5620310cbbd8ece7
+
+        // 2^120 * 8 * G
+
+        .quad   0x528993434934d643
+        .quad   0xb9dbf806a51222f5
+        .quad   0x8f6d878fc3f41c22
+        .quad   0x37676a2a4d9d9730
+        .quad   0x6646b5f477e285d6
+        .quad   0x40e8ff676c8f6193
+        .quad   0xa6ec7311abb594dd
+        .quad   0x7ec846f3658cec4d
+        .quad   0x9b5e8f3f1da22ec7
+        .quad   0x130f1d776c01cd13
+        .quad   0x214c8fcfa2989fb8
+        .quad   0x6daaf723399b9dd5
+
+        // 2^124 * 1 * G
+
+        .quad   0x591e4a5610628564
+        .quad   0x2a4bb87ca8b4df34
+        .quad   0xde2a2572e7a38e43
+        .quad   0x3cbdabd9fee5046e
+        .quad   0x81aebbdd2cd13070
+        .quad   0x962e4325f85a0e9e
+        .quad   0xde9391aacadffecb
+        .quad   0x53177fda52c230e6
+        .quad   0xa7bc970650b9de79
+        .quad   0x3d12a7fbc301b59b
+        .quad   0x02652e68d36ae38c
+        .quad   0x79d739835a6199dc
+
+        // 2^124 * 2 * G
+
+        .quad   0xd9354df64131c1bd
+        .quad   0x758094a186ec5822
+        .quad   0x4464ee12e459f3c2
+        .quad   0x6c11fce4cb133282
+        .quad   0x21c9d9920d591737
+        .quad   0x9bea41d2e9b46cd6
+        .quad   0xe20e84200d89bfca
+        .quad   0x79d99f946eae5ff8
+        .quad   0xf17b483568673205
+        .quad   0x387deae83caad96c
+        .quad   0x61b471fd56ffe386
+        .quad   0x31741195b745a599
+
+        // 2^124 * 3 * G
+
+        .quad   0xe8d10190b77a360b
+        .quad   0x99b983209995e702
+        .quad   0xbd4fdff8fa0247aa
+        .quad   0x2772e344e0d36a87
+        .quad   0x17f8ba683b02a047
+        .quad   0x50212096feefb6c8
+        .quad   0x70139be21556cbe2
+        .quad   0x203e44a11d98915b
+        .quad   0xd6863eba37b9e39f
+        .quad   0x105bc169723b5a23
+        .quad   0x104f6459a65c0762
+        .quad   0x567951295b4d38d4
+
+        // 2^124 * 4 * G
+
+        .quad   0x535fd60613037524
+        .quad   0xe210adf6b0fbc26a
+        .quad   0xac8d0a9b23e990ae
+        .quad   0x47204d08d72fdbf9
+        .quad   0x07242eb30d4b497f
+        .quad   0x1ef96306b9bccc87
+        .quad   0x37950934d8116f45
+        .quad   0x05468d6201405b04
+        .quad   0x00f565a9f93267de
+        .quad   0xcecfd78dc0d58e8a
+        .quad   0xa215e2dcf318e28e
+        .quad   0x4599ee919b633352
+
+        // 2^124 * 5 * G
+
+        .quad   0xd3c220ca70e0e76b
+        .quad   0xb12bea58ea9f3094
+        .quad   0x294ddec8c3271282
+        .quad   0x0c3539e1a1d1d028
+        .quad   0xac746d6b861ae579
+        .quad   0x31ab0650f6aea9dc
+        .quad   0x241d661140256d4c
+        .quad   0x2f485e853d21a5de
+        .quad   0x329744839c0833f3
+        .quad   0x6fe6257fd2abc484
+        .quad   0x5327d1814b358817
+        .quad   0x65712585893fe9bc
+
+        // 2^124 * 6 * G
+
+        .quad   0x9c102fb732a61161
+        .quad   0xe48e10dd34d520a8
+        .quad   0x365c63546f9a9176
+        .quad   0x32f6fe4c046f6006
+        .quad   0x81c29f1bd708ee3f
+        .quad   0xddcb5a05ae6407d0
+        .quad   0x97aec1d7d2a3eba7
+        .quad   0x1590521a91d50831
+        .quad   0x40a3a11ec7910acc
+        .quad   0x9013dff8f16d27ae
+        .quad   0x1a9720d8abb195d4
+        .quad   0x1bb9fe452ea98463
+
+        // 2^124 * 7 * G
+
+        .quad   0xe9d1d950b3d54f9e
+        .quad   0x2d5f9cbee00d33c1
+        .quad   0x51c2c656a04fc6ac
+        .quad   0x65c091ee3c1cbcc9
+        .quad   0xcf5e6c95cc36747c
+        .quad   0x294201536b0bc30d
+        .quad   0x453ac67cee797af0
+        .quad   0x5eae6ab32a8bb3c9
+        .quad   0x7083661114f118ea
+        .quad   0x2b37b87b94349cad
+        .quad   0x7273f51cb4e99f40
+        .quad   0x78a2a95823d75698
+
+        // 2^124 * 8 * G
+
+        .quad   0xa2b072e95c8c2ace
+        .quad   0x69cffc96651e9c4b
+        .quad   0x44328ef842e7b42b
+        .quad   0x5dd996c122aadeb3
+        .quad   0xb4f23c425ef83207
+        .quad   0xabf894d3c9a934b5
+        .quad   0xd0708c1339fd87f7
+        .quad   0x1876789117166130
+        .quad   0x925b5ef0670c507c
+        .quad   0x819bc842b93c33bf
+        .quad   0x10792e9a70dd003f
+        .quad   0x59ad4b7a6e28dc74
+
+        // 2^128 * 1 * G
+
+        .quad   0x5f3a7562eb3dbe47
+        .quad   0xf7ea38548ebda0b8
+        .quad   0x00c3e53145747299
+        .quad   0x1304e9e71627d551
+        .quad   0x583b04bfacad8ea2
+        .quad   0x29b743e8148be884
+        .quad   0x2b1e583b0810c5db
+        .quad   0x2b5449e58eb3bbaa
+        .quad   0x789814d26adc9cfe
+        .quad   0x3c1bab3f8b48dd0b
+        .quad   0xda0fe1fff979c60a
+        .quad   0x4468de2d7c2dd693
+
+        // 2^128 * 2 * G
+
+        .quad   0x51bb355e9419469e
+        .quad   0x33e6dc4c23ddc754
+        .quad   0x93a5b6d6447f9962
+        .quad   0x6cce7c6ffb44bd63
+        .quad   0x4b9ad8c6f86307ce
+        .quad   0x21113531435d0c28
+        .quad   0xd4a866c5657a772c
+        .quad   0x5da6427e63247352
+        .quad   0x1a94c688deac22ca
+        .quad   0xb9066ef7bbae1ff8
+        .quad   0x88ad8c388d59580f
+        .quad   0x58f29abfe79f2ca8
+
+        // 2^128 * 3 * G
+
+        .quad   0xe90ecfab8de73e68
+        .quad   0x54036f9f377e76a5
+        .quad   0xf0495b0bbe015982
+        .quad   0x577629c4a7f41e36
+        .quad   0x4b5a64bf710ecdf6
+        .quad   0xb14ce538462c293c
+        .quad   0x3643d056d50b3ab9
+        .quad   0x6af93724185b4870
+        .quad   0x3220024509c6a888
+        .quad   0xd2e036134b558973
+        .quad   0x83e236233c33289f
+        .quad   0x701f25bb0caec18f
+
+        // 2^128 * 4 * G
+
+        .quad   0xc3a8b0f8e4616ced
+        .quad   0xf700660e9e25a87d
+        .quad   0x61e3061ff4bca59c
+        .quad   0x2e0c92bfbdc40be9
+        .quad   0x9d18f6d97cbec113
+        .quad   0x844a06e674bfdbe4
+        .quad   0x20f5b522ac4e60d6
+        .quad   0x720a5bc050955e51
+        .quad   0x0c3f09439b805a35
+        .quad   0xe84e8b376242abfc
+        .quad   0x691417f35c229346
+        .quad   0x0e9b9cbb144ef0ec
+
+        // 2^128 * 5 * G
+
+        .quad   0xfbbad48ffb5720ad
+        .quad   0xee81916bdbf90d0e
+        .quad   0xd4813152635543bf
+        .quad   0x221104eb3f337bd8
+        .quad   0x8dee9bd55db1beee
+        .quad   0xc9c3ab370a723fb9
+        .quad   0x44a8f1bf1c68d791
+        .quad   0x366d44191cfd3cde
+        .quad   0x9e3c1743f2bc8c14
+        .quad   0x2eda26fcb5856c3b
+        .quad   0xccb82f0e68a7fb97
+        .quad   0x4167a4e6bc593244
+
+        // 2^128 * 6 * G
+
+        .quad   0x643b9d2876f62700
+        .quad   0x5d1d9d400e7668eb
+        .quad   0x1b4b430321fc0684
+        .quad   0x7938bb7e2255246a
+        .quad   0xc2be2665f8ce8fee
+        .quad   0xe967ff14e880d62c
+        .quad   0xf12e6e7e2f364eee
+        .quad   0x34b33370cb7ed2f6
+        .quad   0xcdc591ee8681d6cc
+        .quad   0xce02109ced85a753
+        .quad   0xed7485c158808883
+        .quad   0x1176fc6e2dfe65e4
+
+        // 2^128 * 7 * G
+
+        .quad   0xb4af6cd05b9c619b
+        .quad   0x2ddfc9f4b2a58480
+        .quad   0x3d4fa502ebe94dc4
+        .quad   0x08fc3a4c677d5f34
+        .quad   0xdb90e28949770eb8
+        .quad   0x98fbcc2aacf440a3
+        .quad   0x21354ffeded7879b
+        .quad   0x1f6a3e54f26906b6
+        .quad   0x60a4c199d30734ea
+        .quad   0x40c085b631165cd6
+        .quad   0xe2333e23f7598295
+        .quad   0x4f2fad0116b900d1
+
+        // 2^128 * 8 * G
+
+        .quad   0x44beb24194ae4e54
+        .quad   0x5f541c511857ef6c
+        .quad   0xa61e6b2d368d0498
+        .quad   0x445484a4972ef7ab
+        .quad   0x962cd91db73bb638
+        .quad   0xe60577aafc129c08
+        .quad   0x6f619b39f3b61689
+        .quad   0x3451995f2944ee81
+        .quad   0x9152fcd09fea7d7c
+        .quad   0x4a816c94b0935cf6
+        .quad   0x258e9aaa47285c40
+        .quad   0x10b89ca6042893b7
+
+        // 2^132 * 1 * G
+
+        .quad   0x9b2a426e3b646025
+        .quad   0x32127190385ce4cf
+        .quad   0xa25cffc2dd6dea45
+        .quad   0x06409010bea8de75
+        .quad   0xd67cded679d34aa0
+        .quad   0xcc0b9ec0cc4db39f
+        .quad   0xa535a456e35d190f
+        .quad   0x2e05d9eaf61f6fef
+        .quad   0xc447901ad61beb59
+        .quad   0x661f19bce5dc880a
+        .quad   0x24685482b7ca6827
+        .quad   0x293c778cefe07f26
+
+        // 2^132 * 2 * G
+
+        .quad   0x86809e7007069096
+        .quad   0xaad75b15e4e50189
+        .quad   0x07f35715a21a0147
+        .quad   0x0487f3f112815d5e
+        .quad   0x16c795d6a11ff200
+        .quad   0xcb70d0e2b15815c9
+        .quad   0x89f293209b5395b5
+        .quad   0x50b8c2d031e47b4f
+        .quad   0x48350c08068a4962
+        .quad   0x6ffdd05351092c9a
+        .quad   0x17af4f4aaf6fc8dd
+        .quad   0x4b0553b53cdba58b
+
+        // 2^132 * 3 * G
+
+        .quad   0x9c65fcbe1b32ff79
+        .quad   0xeb75ea9f03b50f9b
+        .quad   0xfced2a6c6c07e606
+        .quad   0x35106cd551717908
+        .quad   0xbf05211b27c152d4
+        .quad   0x5ec26849bd1af639
+        .quad   0x5e0b2caa8e6fab98
+        .quad   0x054c8bdd50bd0840
+        .quad   0x38a0b12f1dcf073d
+        .quad   0x4b60a8a3b7f6a276
+        .quad   0xfed5ac25d3404f9a
+        .quad   0x72e82d5e5505c229
+
+        // 2^132 * 4 * G
+
+        .quad   0x6b0b697ff0d844c8
+        .quad   0xbb12f85cd979cb49
+        .quad   0xd2a541c6c1da0f1f
+        .quad   0x7b7c242958ce7211
+        .quad   0x00d9cdfd69771d02
+        .quad   0x410276cd6cfbf17e
+        .quad   0x4c45306c1cb12ec7
+        .quad   0x2857bf1627500861
+        .quad   0x9f21903f0101689e
+        .quad   0xd779dfd3bf861005
+        .quad   0xa122ee5f3deb0f1b
+        .quad   0x510df84b485a00d4
+
+        // 2^132 * 5 * G
+
+        .quad   0xa54133bb9277a1fa
+        .quad   0x74ec3b6263991237
+        .quad   0x1a3c54dc35d2f15a
+        .quad   0x2d347144e482ba3a
+        .quad   0x24b3c887c70ac15e
+        .quad   0xb0f3a557fb81b732
+        .quad   0x9b2cde2fe578cc1b
+        .quad   0x4cf7ed0703b54f8e
+        .quad   0x6bd47c6598fbee0f
+        .quad   0x9e4733e2ab55be2d
+        .quad   0x1093f624127610c5
+        .quad   0x4e05e26ad0a1eaa4
+
+        // 2^132 * 6 * G
+
+        .quad   0xda9b6b624b531f20
+        .quad   0x429a760e77509abb
+        .quad   0xdbe9f522e823cb80
+        .quad   0x618f1856880c8f82
+        .quad   0x1833c773e18fe6c0
+        .quad   0xe3c4711ad3c87265
+        .quad   0x3bfd3c4f0116b283
+        .quad   0x1955875eb4cd4db8
+        .quad   0x6da6de8f0e399799
+        .quad   0x7ad61aa440fda178
+        .quad   0xb32cd8105e3563dd
+        .quad   0x15f6beae2ae340ae
+
+        // 2^132 * 7 * G
+
+        .quad   0x862bcb0c31ec3a62
+        .quad   0x810e2b451138f3c2
+        .quad   0x788ec4b839dac2a4
+        .quad   0x28f76867ae2a9281
+        .quad   0xba9a0f7b9245e215
+        .quad   0xf368612dd98c0dbb
+        .quad   0x2e84e4cbf220b020
+        .quad   0x6ba92fe962d90eda
+        .quad   0x3e4df9655884e2aa
+        .quad   0xbd62fbdbdbd465a5
+        .quad   0xd7596caa0de9e524
+        .quad   0x6e8042ccb2b1b3d7
+
+        // 2^132 * 8 * G
+
+        .quad   0xf10d3c29ce28ca6e
+        .quad   0xbad34540fcb6093d
+        .quad   0xe7426ed7a2ea2d3f
+        .quad   0x08af9d4e4ff298b9
+        .quad   0x1530653616521f7e
+        .quad   0x660d06b896203dba
+        .quad   0x2d3989bc545f0879
+        .quad   0x4b5303af78ebd7b0
+        .quad   0x72f8a6c3bebcbde8
+        .quad   0x4f0fca4adc3a8e89
+        .quad   0x6fa9d4e8c7bfdf7a
+        .quad   0x0dcf2d679b624eb7
+
+        // 2^136 * 1 * G
+
+        .quad   0x3d5947499718289c
+        .quad   0x12ebf8c524533f26
+        .quad   0x0262bfcb14c3ef15
+        .quad   0x20b878d577b7518e
+        .quad   0x753941be5a45f06e
+        .quad   0xd07caeed6d9c5f65
+        .quad   0x11776b9c72ff51b6
+        .quad   0x17d2d1d9ef0d4da9
+        .quad   0x27f2af18073f3e6a
+        .quad   0xfd3fe519d7521069
+        .quad   0x22e3b72c3ca60022
+        .quad   0x72214f63cc65c6a7
+
+        // 2^136 * 2 * G
+
+        .quad   0xb4e37f405307a693
+        .quad   0xaba714d72f336795
+        .quad   0xd6fbd0a773761099
+        .quad   0x5fdf48c58171cbc9
+        .quad   0x1d9db7b9f43b29c9
+        .quad   0xd605824a4f518f75
+        .quad   0xf2c072bd312f9dc4
+        .quad   0x1f24ac855a1545b0
+        .quad   0x24d608328e9505aa
+        .quad   0x4748c1d10c1420ee
+        .quad   0xc7ffe45c06fb25a2
+        .quad   0x00ba739e2ae395e6
+
+        // 2^136 * 3 * G
+
+        .quad   0x592e98de5c8790d6
+        .quad   0xe5bfb7d345c2a2df
+        .quad   0x115a3b60f9b49922
+        .quad   0x03283a3e67ad78f3
+        .quad   0xae4426f5ea88bb26
+        .quad   0x360679d984973bfb
+        .quad   0x5c9f030c26694e50
+        .quad   0x72297de7d518d226
+        .quad   0x48241dc7be0cb939
+        .quad   0x32f19b4d8b633080
+        .quad   0xd3dfc90d02289308
+        .quad   0x05e1296846271945
+
+        // 2^136 * 4 * G
+
+        .quad   0xba82eeb32d9c495a
+        .quad   0xceefc8fcf12bb97c
+        .quad   0xb02dabae93b5d1e0
+        .quad   0x39c00c9c13698d9b
+        .quad   0xadbfbbc8242c4550
+        .quad   0xbcc80cecd03081d9
+        .quad   0x843566a6f5c8df92
+        .quad   0x78cf25d38258ce4c
+        .quad   0x15ae6b8e31489d68
+        .quad   0xaa851cab9c2bf087
+        .quad   0xc9a75a97f04efa05
+        .quad   0x006b52076b3ff832
+
+        // 2^136 * 5 * G
+
+        .quad   0x29e0cfe19d95781c
+        .quad   0xb681df18966310e2
+        .quad   0x57df39d370516b39
+        .quad   0x4d57e3443bc76122
+        .quad   0xf5cb7e16b9ce082d
+        .quad   0x3407f14c417abc29
+        .quad   0xd4b36bce2bf4a7ab
+        .quad   0x7de2e9561a9f75ce
+        .quad   0xde70d4f4b6a55ecb
+        .quad   0x4801527f5d85db99
+        .quad   0xdbc9c440d3ee9a81
+        .quad   0x6b2a90af1a6029ed
+
+        // 2^136 * 6 * G
+
+        .quad   0x6923f4fc9ae61e97
+        .quad   0x5735281de03f5fd1
+        .quad   0xa764ae43e6edd12d
+        .quad   0x5fd8f4e9d12d3e4a
+        .quad   0x77ebf3245bb2d80a
+        .quad   0xd8301b472fb9079b
+        .quad   0xc647e6f24cee7333
+        .quad   0x465812c8276c2109
+        .quad   0x4d43beb22a1062d9
+        .quad   0x7065fb753831dc16
+        .quad   0x180d4a7bde2968d7
+        .quad   0x05b32c2b1cb16790
+
+        // 2^136 * 7 * G
+
+        .quad   0xc8c05eccd24da8fd
+        .quad   0xa1cf1aac05dfef83
+        .quad   0xdbbeeff27df9cd61
+        .quad   0x3b5556a37b471e99
+        .quad   0xf7fca42c7ad58195
+        .quad   0x3214286e4333f3cc
+        .quad   0xb6c29d0d340b979d
+        .quad   0x31771a48567307e1
+        .quad   0x32b0c524e14dd482
+        .quad   0xedb351541a2ba4b6
+        .quad   0xa3d16048282b5af3
+        .quad   0x4fc079d27a7336eb
+
+        // 2^136 * 8 * G
+
+        .quad   0x51c938b089bf2f7f
+        .quad   0x2497bd6502dfe9a7
+        .quad   0xffffc09c7880e453
+        .quad   0x124567cecaf98e92
+        .quad   0xdc348b440c86c50d
+        .quad   0x1337cbc9cc94e651
+        .quad   0x6422f74d643e3cb9
+        .quad   0x241170c2bae3cd08
+        .quad   0x3ff9ab860ac473b4
+        .quad   0xf0911dee0113e435
+        .quad   0x4ae75060ebc6c4af
+        .quad   0x3f8612966c87000d
+
+        // 2^140 * 1 * G
+
+        .quad   0x0c9c5303f7957be4
+        .quad   0xa3c31a20e085c145
+        .quad   0xb0721d71d0850050
+        .quad   0x0aba390eab0bf2da
+        .quad   0x529fdffe638c7bf3
+        .quad   0xdf2b9e60388b4995
+        .quad   0xe027b34f1bad0249
+        .quad   0x7bc92fc9b9fa74ed
+        .quad   0x9f97ef2e801ad9f9
+        .quad   0x83697d5479afda3a
+        .quad   0xe906b3ffbd596b50
+        .quad   0x02672b37dd3fb8e0
+
+        // 2^140 * 2 * G
+
+        .quad   0x48b2ca8b260885e4
+        .quad   0xa4286bec82b34c1c
+        .quad   0x937e1a2617f58f74
+        .quad   0x741d1fcbab2ca2a5
+        .quad   0xee9ba729398ca7f5
+        .quad   0xeb9ca6257a4849db
+        .quad   0x29eb29ce7ec544e1
+        .quad   0x232ca21ef736e2c8
+        .quad   0xbf61423d253fcb17
+        .quad   0x08803ceafa39eb14
+        .quad   0xf18602df9851c7af
+        .quad   0x0400f3a049e3414b
+
+        // 2^140 * 3 * G
+
+        .quad   0xabce0476ba61c55b
+        .quad   0x36a3d6d7c4d39716
+        .quad   0x6eb259d5e8d82d09
+        .quad   0x0c9176e984d756fb
+        .quad   0x2efba412a06e7b06
+        .quad   0x146785452c8d2560
+        .quad   0xdf9713ebd67a91c7
+        .quad   0x32830ac7157eadf3
+        .quad   0x0e782a7ab73769e8
+        .quad   0x04a05d7875b18e2c
+        .quad   0x29525226ebcceae1
+        .quad   0x0d794f8383eba820
+
+        // 2^140 * 4 * G
+
+        .quad   0xff35f5cb9e1516f4
+        .quad   0xee805bcf648aae45
+        .quad   0xf0d73c2bb93a9ef3
+        .quad   0x097b0bf22092a6c2
+        .quad   0x7be44ce7a7a2e1ac
+        .quad   0x411fd93efad1b8b7
+        .quad   0x1734a1d70d5f7c9b
+        .quad   0x0d6592233127db16
+        .quad   0xc48bab1521a9d733
+        .quad   0xa6c2eaead61abb25
+        .quad   0x625c6c1cc6cb4305
+        .quad   0x7fc90fea93eb3a67
+
+        // 2^140 * 5 * G
+
+        .quad   0x0408f1fe1f5c5926
+        .quad   0x1a8f2f5e3b258bf4
+        .quad   0x40a951a2fdc71669
+        .quad   0x6598ee93c98b577e
+        .quad   0xc527deb59c7cb23d
+        .quad   0x955391695328404e
+        .quad   0xd64392817ccf2c7a
+        .quad   0x6ce97dabf7d8fa11
+        .quad   0x25b5a8e50ef7c48f
+        .quad   0xeb6034116f2ce532
+        .quad   0xc5e75173e53de537
+        .quad   0x73119fa08c12bb03
+
+        // 2^140 * 6 * G
+
+        .quad   0xed30129453f1a4cb
+        .quad   0xbce621c9c8f53787
+        .quad   0xfacb2b1338bee7b9
+        .quad   0x3025798a9ea8428c
+        .quad   0x7845b94d21f4774d
+        .quad   0xbf62f16c7897b727
+        .quad   0x671857c03c56522b
+        .quad   0x3cd6a85295621212
+        .quad   0x3fecde923aeca999
+        .quad   0xbdaa5b0062e8c12f
+        .quad   0x67b99dfc96988ade
+        .quad   0x3f52c02852661036
+
+        // 2^140 * 7 * G
+
+        .quad   0xffeaa48e2a1351c6
+        .quad   0x28624754fa7f53d7
+        .quad   0x0b5ba9e57582ddf1
+        .quad   0x60c0104ba696ac59
+        .quad   0x9258bf99eec416c6
+        .quad   0xac8a5017a9d2f671
+        .quad   0x629549ab16dea4ab
+        .quad   0x05d0e85c99091569
+        .quad   0x051de020de9cbe97
+        .quad   0xfa07fc56b50bcf74
+        .quad   0x378cec9f0f11df65
+        .quad   0x36853c69ab96de4d
+
+        // 2^140 * 8 * G
+
+        .quad   0x36d9b8de78f39b2d
+        .quad   0x7f42ed71a847b9ec
+        .quad   0x241cd1d679bd3fde
+        .quad   0x6a704fec92fbce6b
+        .quad   0x4433c0b0fac5e7be
+        .quad   0x724bae854c08dcbe
+        .quad   0xf1f24cc446978f9b
+        .quad   0x4a0aff6d62825fc8
+        .quad   0xe917fb9e61095301
+        .quad   0xc102df9402a092f8
+        .quad   0xbf09e2f5fa66190b
+        .quad   0x681109bee0dcfe37
+
+        // 2^144 * 1 * G
+
+        .quad   0x559a0cc9782a0dde
+        .quad   0x551dcdb2ea718385
+        .quad   0x7f62865b31ef238c
+        .quad   0x504aa7767973613d
+        .quad   0x9c18fcfa36048d13
+        .quad   0x29159db373899ddd
+        .quad   0xdc9f350b9f92d0aa
+        .quad   0x26f57eee878a19d4
+        .quad   0x0cab2cd55687efb1
+        .quad   0x5180d162247af17b
+        .quad   0x85c15a344f5a2467
+        .quad   0x4041943d9dba3069
+
+        // 2^144 * 2 * G
+
+        .quad   0xc3c0eeba43ebcc96
+        .quad   0x8d749c9c26ea9caf
+        .quad   0xd9fa95ee1c77ccc6
+        .quad   0x1420a1d97684340f
+        .quad   0x4b217743a26caadd
+        .quad   0x47a6b424648ab7ce
+        .quad   0xcb1d4f7a03fbc9e3
+        .quad   0x12d931429800d019
+        .quad   0x00c67799d337594f
+        .quad   0x5e3c5140b23aa47b
+        .quad   0x44182854e35ff395
+        .quad   0x1b4f92314359a012
+
+        // 2^144 * 3 * G
+
+        .quad   0x3e5c109d89150951
+        .quad   0x39cefa912de9696a
+        .quad   0x20eae43f975f3020
+        .quad   0x239b572a7f132dae
+        .quad   0x33cf3030a49866b1
+        .quad   0x251f73d2215f4859
+        .quad   0xab82aa4051def4f6
+        .quad   0x5ff191d56f9a23f6
+        .quad   0x819ed433ac2d9068
+        .quad   0x2883ab795fc98523
+        .quad   0xef4572805593eb3d
+        .quad   0x020c526a758f36cb
+
+        // 2^144 * 4 * G
+
+        .quad   0x779834f89ed8dbbc
+        .quad   0xc8f2aaf9dc7ca46c
+        .quad   0xa9524cdca3e1b074
+        .quad   0x02aacc4615313877
+        .quad   0xe931ef59f042cc89
+        .quad   0x2c589c9d8e124bb6
+        .quad   0xadc8e18aaec75997
+        .quad   0x452cfe0a5602c50c
+        .quad   0x86a0f7a0647877df
+        .quad   0xbbc464270e607c9f
+        .quad   0xab17ea25f1fb11c9
+        .quad   0x4cfb7d7b304b877b
+
+        // 2^144 * 5 * G
+
+        .quad   0x72b43d6cb89b75fe
+        .quad   0x54c694d99c6adc80
+        .quad   0xb8c3aa373ee34c9f
+        .quad   0x14b4622b39075364
+        .quad   0xe28699c29789ef12
+        .quad   0x2b6ecd71df57190d
+        .quad   0xc343c857ecc970d0
+        .quad   0x5b1d4cbc434d3ac5
+        .quad   0xb6fb2615cc0a9f26
+        .quad   0x3a4f0e2bb88dcce5
+        .quad   0x1301498b3369a705
+        .quad   0x2f98f71258592dd1
+
+        // 2^144 * 6 * G
+
+        .quad   0x0c94a74cb50f9e56
+        .quad   0x5b1ff4a98e8e1320
+        .quad   0x9a2acc2182300f67
+        .quad   0x3a6ae249d806aaf9
+        .quad   0x2e12ae444f54a701
+        .quad   0xfcfe3ef0a9cbd7de
+        .quad   0xcebf890d75835de0
+        .quad   0x1d8062e9e7614554
+        .quad   0x657ada85a9907c5a
+        .quad   0x1a0ea8b591b90f62
+        .quad   0x8d0e1dfbdf34b4e9
+        .quad   0x298b8ce8aef25ff3
+
+        // 2^144 * 7 * G
+
+        .quad   0x2a927953eff70cb2
+        .quad   0x4b89c92a79157076
+        .quad   0x9418457a30a7cf6a
+        .quad   0x34b8a8404d5ce485
+        .quad   0x837a72ea0a2165de
+        .quad   0x3fab07b40bcf79f6
+        .quad   0x521636c77738ae70
+        .quad   0x6ba6271803a7d7dc
+        .quad   0xc26eecb583693335
+        .quad   0xd5a813df63b5fefd
+        .quad   0xa293aa9aa4b22573
+        .quad   0x71d62bdd465e1c6a
+
+        // 2^144 * 8 * G
+
+        .quad   0x6533cc28d378df80
+        .quad   0xf6db43790a0fa4b4
+        .quad   0xe3645ff9f701da5a
+        .quad   0x74d5f317f3172ba4
+        .quad   0xcd2db5dab1f75ef5
+        .quad   0xd77f95cf16b065f5
+        .quad   0x14571fea3f49f085
+        .quad   0x1c333621262b2b3d
+        .quad   0xa86fe55467d9ca81
+        .quad   0x398b7c752b298c37
+        .quad   0xda6d0892e3ac623b
+        .quad   0x4aebcc4547e9d98c
+
+        // 2^148 * 1 * G
+
+        .quad   0x53175a7205d21a77
+        .quad   0xb0c04422d3b934d4
+        .quad   0xadd9f24bdd5deadc
+        .quad   0x074f46e69f10ff8c
+        .quad   0x0de9b204a059a445
+        .quad   0xe15cb4aa4b17ad0f
+        .quad   0xe1bbec521f79c557
+        .quad   0x2633f1b9d071081b
+        .quad   0xc1fb4177018b9910
+        .quad   0xa6ea20dc6c0fe140
+        .quad   0xd661f3e74354c6ff
+        .quad   0x5ecb72e6f1a3407a
+
+        // 2^148 * 2 * G
+
+        .quad   0xa515a31b2259fb4e
+        .quad   0x0960f3972bcac52f
+        .quad   0xedb52fec8d3454cb
+        .quad   0x382e2720c476c019
+        .quad   0xfeeae106e8e86997
+        .quad   0x9863337f98d09383
+        .quad   0x9470480eaa06ebef
+        .quad   0x038b6898d4c5c2d0
+        .quad   0xf391c51d8ace50a6
+        .quad   0x3142d0b9ae2d2948
+        .quad   0xdb4d5a1a7f24ca80
+        .quad   0x21aeba8b59250ea8
+
+        // 2^148 * 3 * G
+
+        .quad   0x24f13b34cf405530
+        .quad   0x3c44ea4a43088af7
+        .quad   0x5dd5c5170006a482
+        .quad   0x118eb8f8890b086d
+        .quad   0x53853600f0087f23
+        .quad   0x4c461879da7d5784
+        .quad   0x6af303deb41f6860
+        .quad   0x0a3c16c5c27c18ed
+        .quad   0x17e49c17cc947f3d
+        .quad   0xccc6eda6aac1d27b
+        .quad   0xdf6092ceb0f08e56
+        .quad   0x4909b3e22c67c36b
+
+        // 2^148 * 4 * G
+
+        .quad   0x9c9c85ea63fe2e89
+        .quad   0xbe1baf910e9412ec
+        .quad   0x8f7baa8a86fbfe7b
+        .quad   0x0fb17f9fef968b6c
+        .quad   0x59a16676706ff64e
+        .quad   0x10b953dd0d86a53d
+        .quad   0x5848e1e6ce5c0b96
+        .quad   0x2d8b78e712780c68
+        .quad   0x79d5c62eafc3902b
+        .quad   0x773a215289e80728
+        .quad   0xc38ae640e10120b9
+        .quad   0x09ae23717b2b1a6d
+
+        // 2^148 * 5 * G
+
+        .quad   0xbb6a192a4e4d083c
+        .quad   0x34ace0630029e192
+        .quad   0x98245a59aafabaeb
+        .quad   0x6d9c8a9ada97faac
+        .quad   0x10ab8fa1ad32b1d0
+        .quad   0xe9aced1be2778b24
+        .quad   0xa8856bc0373de90f
+        .quad   0x66f35ddddda53996
+        .quad   0xd27d9afb24997323
+        .quad   0x1bb7e07ef6f01d2e
+        .quad   0x2ba7472df52ecc7f
+        .quad   0x03019b4f646f9dc8
+
+        // 2^148 * 6 * G
+
+        .quad   0x04a186b5565345cd
+        .quad   0xeee76610bcc4116a
+        .quad   0x689c73b478fb2a45
+        .quad   0x387dcbff65697512
+        .quad   0xaf09b214e6b3dc6b
+        .quad   0x3f7573b5ad7d2f65
+        .quad   0xd019d988100a23b0
+        .quad   0x392b63a58b5c35f7
+        .quad   0x4093addc9c07c205
+        .quad   0xc565be15f532c37e
+        .quad   0x63dbecfd1583402a
+        .quad   0x61722b4aef2e032e
+
+        // 2^148 * 7 * G
+
+        .quad   0x0012aafeecbd47af
+        .quad   0x55a266fb1cd46309
+        .quad   0xf203eb680967c72c
+        .quad   0x39633944ca3c1429
+        .quad   0xd6b07a5581cb0e3c
+        .quad   0x290ff006d9444969
+        .quad   0x08680b6a16dcda1f
+        .quad   0x5568d2b75a06de59
+        .quad   0x8d0cb88c1b37cfe1
+        .quad   0x05b6a5a3053818f3
+        .quad   0xf2e9bc04b787d959
+        .quad   0x6beba1249add7f64
+
+        // 2^148 * 8 * G
+
+        .quad   0x1d06005ca5b1b143
+        .quad   0x6d4c6bb87fd1cda2
+        .quad   0x6ef5967653fcffe7
+        .quad   0x097c29e8c1ce1ea5
+        .quad   0x5c3cecb943f5a53b
+        .quad   0x9cc9a61d06c08df2
+        .quad   0xcfba639a85895447
+        .quad   0x5a845ae80df09fd5
+        .quad   0x4ce97dbe5deb94ca
+        .quad   0x38d0a4388c709c48
+        .quad   0xc43eced4a169d097
+        .quad   0x0a1249fff7e587c3
+
+        // 2^152 * 1 * G
+
+        .quad   0x12f0071b276d01c9
+        .quad   0xe7b8bac586c48c70
+        .quad   0x5308129b71d6fba9
+        .quad   0x5d88fbf95a3db792
+        .quad   0x0b408d9e7354b610
+        .quad   0x806b32535ba85b6e
+        .quad   0xdbe63a034a58a207
+        .quad   0x173bd9ddc9a1df2c
+        .quad   0x2b500f1efe5872df
+        .quad   0x58d6582ed43918c1
+        .quad   0xe6ed278ec9673ae0
+        .quad   0x06e1cd13b19ea319
+
+        // 2^152 * 2 * G
+
+        .quad   0x40d0ad516f166f23
+        .quad   0x118e32931fab6abe
+        .quad   0x3fe35e14a04d088e
+        .quad   0x3080603526e16266
+        .quad   0x472baf629e5b0353
+        .quad   0x3baa0b90278d0447
+        .quad   0x0c785f469643bf27
+        .quad   0x7f3a6a1a8d837b13
+        .quad   0xf7e644395d3d800b
+        .quad   0x95a8d555c901edf6
+        .quad   0x68cd7830592c6339
+        .quad   0x30d0fded2e51307e
+
+        // 2^152 * 3 * G
+
+        .quad   0xe0594d1af21233b3
+        .quad   0x1bdbe78ef0cc4d9c
+        .quad   0x6965187f8f499a77
+        .quad   0x0a9214202c099868
+        .quad   0x9cb4971e68b84750
+        .quad   0xa09572296664bbcf
+        .quad   0x5c8de72672fa412b
+        .quad   0x4615084351c589d9
+        .quad   0xbc9019c0aeb9a02e
+        .quad   0x55c7110d16034cae
+        .quad   0x0e6df501659932ec
+        .quad   0x3bca0d2895ca5dfe
+
+        // 2^152 * 4 * G
+
+        .quad   0x40f031bc3c5d62a4
+        .quad   0x19fc8b3ecff07a60
+        .quad   0x98183da2130fb545
+        .quad   0x5631deddae8f13cd
+        .quad   0x9c688eb69ecc01bf
+        .quad   0xf0bc83ada644896f
+        .quad   0xca2d955f5f7a9fe2
+        .quad   0x4ea8b4038df28241
+        .quad   0x2aed460af1cad202
+        .quad   0x46305305a48cee83
+        .quad   0x9121774549f11a5f
+        .quad   0x24ce0930542ca463
+
+        // 2^152 * 5 * G
+
+        .quad   0x1fe890f5fd06c106
+        .quad   0xb5c468355d8810f2
+        .quad   0x827808fe6e8caf3e
+        .quad   0x41d4e3c28a06d74b
+        .quad   0x3fcfa155fdf30b85
+        .quad   0xd2f7168e36372ea4
+        .quad   0xb2e064de6492f844
+        .quad   0x549928a7324f4280
+        .quad   0xf26e32a763ee1a2e
+        .quad   0xae91e4b7d25ffdea
+        .quad   0xbc3bd33bd17f4d69
+        .quad   0x491b66dec0dcff6a
+
+        // 2^152 * 6 * G
+
+        .quad   0x98f5b13dc7ea32a7
+        .quad   0xe3d5f8cc7e16db98
+        .quad   0xac0abf52cbf8d947
+        .quad   0x08f338d0c85ee4ac
+        .quad   0x75f04a8ed0da64a1
+        .quad   0xed222caf67e2284b
+        .quad   0x8234a3791f7b7ba4
+        .quad   0x4cf6b8b0b7018b67
+        .quad   0xc383a821991a73bd
+        .quad   0xab27bc01df320c7a
+        .quad   0xc13d331b84777063
+        .quad   0x530d4a82eb078a99
+
+        // 2^152 * 7 * G
+
+        .quad   0x004c3630e1f94825
+        .quad   0x7e2d78268cab535a
+        .quad   0xc7482323cc84ff8b
+        .quad   0x65ea753f101770b9
+        .quad   0x6d6973456c9abf9e
+        .quad   0x257fb2fc4900a880
+        .quad   0x2bacf412c8cfb850
+        .quad   0x0db3e7e00cbfbd5b
+        .quad   0x3d66fc3ee2096363
+        .quad   0x81d62c7f61b5cb6b
+        .quad   0x0fbe044213443b1a
+        .quad   0x02a4ec1921e1a1db
+
+        // 2^152 * 8 * G
+
+        .quad   0x5ce6259a3b24b8a2
+        .quad   0xb8577acc45afa0b8
+        .quad   0xcccbe6e88ba07037
+        .quad   0x3d143c51127809bf
+        .quad   0xf5c86162f1cf795f
+        .quad   0x118c861926ee57f2
+        .quad   0x172124851c063578
+        .quad   0x36d12b5dec067fcf
+        .quad   0x126d279179154557
+        .quad   0xd5e48f5cfc783a0a
+        .quad   0x36bdb6e8df179bac
+        .quad   0x2ef517885ba82859
+
+        // 2^156 * 1 * G
+
+        .quad   0x88bd438cd11e0d4a
+        .quad   0x30cb610d43ccf308
+        .quad   0xe09a0e3791937bcc
+        .quad   0x4559135b25b1720c
+        .quad   0x1ea436837c6da1e9
+        .quad   0xf9c189af1fb9bdbe
+        .quad   0x303001fcce5dd155
+        .quad   0x28a7c99ebc57be52
+        .quad   0xb8fd9399e8d19e9d
+        .quad   0x908191cb962423ff
+        .quad   0xb2b948d747c742a3
+        .quad   0x37f33226d7fb44c4
+
+        // 2^156 * 2 * G
+
+        .quad   0x0dae8767b55f6e08
+        .quad   0x4a43b3b35b203a02
+        .quad   0xe3725a6e80af8c79
+        .quad   0x0f7a7fd1705fa7a3
+        .quad   0x33912553c821b11d
+        .quad   0x66ed42c241e301df
+        .quad   0x066fcc11104222fd
+        .quad   0x307a3b41c192168f
+        .quad   0x8eeb5d076eb55ce0
+        .quad   0x2fc536bfaa0d925a
+        .quad   0xbe81830fdcb6c6e8
+        .quad   0x556c7045827baf52
+
+        // 2^156 * 3 * G
+
+        .quad   0x8e2b517302e9d8b7
+        .quad   0xe3e52269248714e8
+        .quad   0xbd4fbd774ca960b5
+        .quad   0x6f4b4199c5ecada9
+        .quad   0xb94b90022bf44406
+        .quad   0xabd4237eff90b534
+        .quad   0x7600a960faf86d3a
+        .quad   0x2f45abdac2322ee3
+        .quad   0x61af4912c8ef8a6a
+        .quad   0xe58fa4fe43fb6e5e
+        .quad   0xb5afcc5d6fd427cf
+        .quad   0x6a5393281e1e11eb
+
+        // 2^156 * 4 * G
+
+        .quad   0xf3da5139a5d1ee89
+        .quad   0x8145457cff936988
+        .quad   0x3f622fed00e188c4
+        .quad   0x0f513815db8b5a3d
+        .quad   0x0fff04fe149443cf
+        .quad   0x53cac6d9865cddd7
+        .quad   0x31385b03531ed1b7
+        .quad   0x5846a27cacd1039d
+        .quad   0x4ff5cdac1eb08717
+        .quad   0x67e8b29590f2e9bc
+        .quad   0x44093b5e237afa99
+        .quad   0x0d414bed8708b8b2
+
+        // 2^156 * 5 * G
+
+        .quad   0xcfb68265fd0e75f6
+        .quad   0xe45b3e28bb90e707
+        .quad   0x7242a8de9ff92c7a
+        .quad   0x685b3201933202dd
+        .quad   0x81886a92294ac9e8
+        .quad   0x23162b45d55547be
+        .quad   0x94cfbc4403715983
+        .quad   0x50eb8fdb134bc401
+        .quad   0xc0b73ec6d6b330cd
+        .quad   0x84e44807132faff1
+        .quad   0x732b7352c4a5dee1
+        .quad   0x5d7c7cf1aa7cd2d2
+
+        // 2^156 * 6 * G
+
+        .quad   0xaf3b46bf7a4aafa2
+        .quad   0xb78705ec4d40d411
+        .quad   0x114f0c6aca7c15e3
+        .quad   0x3f364faaa9489d4d
+        .quad   0x33d1013e9b73a562
+        .quad   0x925cef5748ec26e1
+        .quad   0xa7fce614dd468058
+        .quad   0x78b0fad41e9aa438
+        .quad   0xbf56a431ed05b488
+        .quad   0xa533e66c9c495c7e
+        .quad   0xe8652baf87f3651a
+        .quad   0x0241800059d66c33
+
+        // 2^156 * 7 * G
+
+        .quad   0xceb077fea37a5be4
+        .quad   0xdb642f02e5a5eeb7
+        .quad   0xc2e6d0c5471270b8
+        .quad   0x4771b65538e4529c
+        .quad   0x28350c7dcf38ea01
+        .quad   0x7c6cdbc0b2917ab6
+        .quad   0xace7cfbe857082f7
+        .quad   0x4d2845aba2d9a1e0
+        .quad   0xbb537fe0447070de
+        .quad   0xcba744436dd557df
+        .quad   0xd3b5a3473600dbcb
+        .quad   0x4aeabbe6f9ffd7f8
+
+        // 2^156 * 8 * G
+
+        .quad   0x4630119e40d8f78c
+        .quad   0xa01a9bc53c710e11
+        .quad   0x486d2b258910dd79
+        .quad   0x1e6c47b3db0324e5
+        .quad   0x6a2134bcc4a9c8f2
+        .quad   0xfbf8fd1c8ace2e37
+        .quad   0x000ae3049911a0ba
+        .quad   0x046e3a616bc89b9e
+        .quad   0x14e65442f03906be
+        .quad   0x4a019d54e362be2a
+        .quad   0x68ccdfec8dc230c7
+        .quad   0x7cfb7e3faf6b861c
+
+        // 2^160 * 1 * G
+
+        .quad   0x4637974e8c58aedc
+        .quad   0xb9ef22fbabf041a4
+        .quad   0xe185d956e980718a
+        .quad   0x2f1b78fab143a8a6
+        .quad   0x96eebffb305b2f51
+        .quad   0xd3f938ad889596b8
+        .quad   0xf0f52dc746d5dd25
+        .quad   0x57968290bb3a0095
+        .quad   0xf71ab8430a20e101
+        .quad   0xf393658d24f0ec47
+        .quad   0xcf7509a86ee2eed1
+        .quad   0x7dc43e35dc2aa3e1
+
+        // 2^160 * 2 * G
+
+        .quad   0x85966665887dd9c3
+        .quad   0xc90f9b314bb05355
+        .quad   0xc6e08df8ef2079b1
+        .quad   0x7ef72016758cc12f
+        .quad   0x5a782a5c273e9718
+        .quad   0x3576c6995e4efd94
+        .quad   0x0f2ed8051f237d3e
+        .quad   0x044fb81d82d50a99
+        .quad   0xc1df18c5a907e3d9
+        .quad   0x57b3371dce4c6359
+        .quad   0xca704534b201bb49
+        .quad   0x7f79823f9c30dd2e
+
+        // 2^160 * 3 * G
+
+        .quad   0x8334d239a3b513e8
+        .quad   0xc13670d4b91fa8d8
+        .quad   0x12b54136f590bd33
+        .quad   0x0a4e0373d784d9b4
+        .quad   0x6a9c1ff068f587ba
+        .quad   0x0827894e0050c8de
+        .quad   0x3cbf99557ded5be7
+        .quad   0x64a9b0431c06d6f0
+        .quad   0x2eb3d6a15b7d2919
+        .quad   0xb0b4f6a0d53a8235
+        .quad   0x7156ce4389a45d47
+        .quad   0x071a7d0ace18346c
+
+        // 2^160 * 4 * G
+
+        .quad   0xd3072daac887ba0b
+        .quad   0x01262905bfa562ee
+        .quad   0xcf543002c0ef768b
+        .quad   0x2c3bcc7146ea7e9c
+        .quad   0xcc0c355220e14431
+        .quad   0x0d65950709b15141
+        .quad   0x9af5621b209d5f36
+        .quad   0x7c69bcf7617755d3
+        .quad   0x07f0d7eb04e8295f
+        .quad   0x10db18252f50f37d
+        .quad   0xe951a9a3171798d7
+        .quad   0x6f5a9a7322aca51d
+
+        // 2^160 * 5 * G
+
+        .quad   0x8ba1000c2f41c6c5
+        .quad   0xc49f79c10cfefb9b
+        .quad   0x4efa47703cc51c9f
+        .quad   0x494e21a2e147afca
+        .quad   0xe729d4eba3d944be
+        .quad   0x8d9e09408078af9e
+        .quad   0x4525567a47869c03
+        .quad   0x02ab9680ee8d3b24
+        .quad   0xefa48a85dde50d9a
+        .quad   0x219a224e0fb9a249
+        .quad   0xfa091f1dd91ef6d9
+        .quad   0x6b5d76cbea46bb34
+
+        // 2^160 * 6 * G
+
+        .quad   0x8857556cec0cd994
+        .quad   0x6472dc6f5cd01dba
+        .quad   0xaf0169148f42b477
+        .quad   0x0ae333f685277354
+        .quad   0xe0f941171e782522
+        .quad   0xf1e6ae74036936d3
+        .quad   0x408b3ea2d0fcc746
+        .quad   0x16fb869c03dd313e
+        .quad   0x288e199733b60962
+        .quad   0x24fc72b4d8abe133
+        .quad   0x4811f7ed0991d03e
+        .quad   0x3f81e38b8f70d075
+
+        // 2^160 * 7 * G
+
+        .quad   0x7f910fcc7ed9affe
+        .quad   0x545cb8a12465874b
+        .quad   0xa8397ed24b0c4704
+        .quad   0x50510fc104f50993
+        .quad   0x0adb7f355f17c824
+        .quad   0x74b923c3d74299a4
+        .quad   0xd57c3e8bcbf8eaf7
+        .quad   0x0ad3e2d34cdedc3d
+        .quad   0x6f0c0fc5336e249d
+        .quad   0x745ede19c331cfd9
+        .quad   0xf2d6fd0009eefe1c
+        .quad   0x127c158bf0fa1ebe
+
+        // 2^160 * 8 * G
+
+        .quad   0xf6197c422e9879a2
+        .quad   0xa44addd452ca3647
+        .quad   0x9b413fc14b4eaccb
+        .quad   0x354ef87d07ef4f68
+        .quad   0xdea28fc4ae51b974
+        .quad   0x1d9973d3744dfe96
+        .quad   0x6240680b873848a8
+        .quad   0x4ed82479d167df95
+        .quad   0xfee3b52260c5d975
+        .quad   0x50352efceb41b0b8
+        .quad   0x8808ac30a9f6653c
+        .quad   0x302d92d20539236d
+
+        // 2^164 * 1 * G
+
+        .quad   0x4c59023fcb3efb7c
+        .quad   0x6c2fcb99c63c2a94
+        .quad   0xba4190e2c3c7e084
+        .quad   0x0e545daea51874d9
+        .quad   0x957b8b8b0df53c30
+        .quad   0x2a1c770a8e60f098
+        .quad   0xbbc7a670345796de
+        .quad   0x22a48f9a90c99bc9
+        .quad   0x6b7dc0dc8d3fac58
+        .quad   0x5497cd6ce6e42bfd
+        .quad   0x542f7d1bf400d305
+        .quad   0x4159f47f048d9136
+
+        // 2^164 * 2 * G
+
+        .quad   0x20ad660839e31e32
+        .quad   0xf81e1bd58405be50
+        .quad   0xf8064056f4dabc69
+        .quad   0x14d23dd4ce71b975
+        .quad   0x748515a8bbd24839
+        .quad   0x77128347afb02b55
+        .quad   0x50ba2ac649a2a17f
+        .quad   0x060525513ad730f1
+        .quad   0xf2398e098aa27f82
+        .quad   0x6d7982bb89a1b024
+        .quad   0xfa694084214dd24c
+        .quad   0x71ab966fa32301c3
+
+        // 2^164 * 3 * G
+
+        .quad   0x2dcbd8e34ded02fc
+        .quad   0x1151f3ec596f22aa
+        .quad   0xbca255434e0328da
+        .quad   0x35768fbe92411b22
+        .quad   0xb1088a0702809955
+        .quad   0x43b273ea0b43c391
+        .quad   0xca9b67aefe0686ed
+        .quad   0x605eecbf8335f4ed
+        .quad   0x83200a656c340431
+        .quad   0x9fcd71678ee59c2f
+        .quad   0x75d4613f71300f8a
+        .quad   0x7a912faf60f542f9
+
+        // 2^164 * 4 * G
+
+        .quad   0xb204585e5edc1a43
+        .quad   0x9f0e16ee5897c73c
+        .quad   0x5b82c0ae4e70483c
+        .quad   0x624a170e2bddf9be
+        .quad   0x253f4f8dfa2d5597
+        .quad   0x25e49c405477130c
+        .quad   0x00c052e5996b1102
+        .quad   0x33cb966e33bb6c4a
+        .quad   0x597028047f116909
+        .quad   0x828ac41c1e564467
+        .quad   0x70417dbde6217387
+        .quad   0x721627aefbac4384
+
+        // 2^164 * 5 * G
+
+        .quad   0x97d03bc38736add5
+        .quad   0x2f1422afc532b130
+        .quad   0x3aa68a057101bbc4
+        .quad   0x4c946cf7e74f9fa7
+        .quad   0xfd3097bc410b2f22
+        .quad   0xf1a05da7b5cfa844
+        .quad   0x61289a1def57ca74
+        .quad   0x245ea199bb821902
+        .quad   0xaedca66978d477f8
+        .quad   0x1898ba3c29117fe1
+        .quad   0xcf73f983720cbd58
+        .quad   0x67da12e6b8b56351
+
+        // 2^164 * 6 * G
+
+        .quad   0x7067e187b4bd6e07
+        .quad   0x6e8f0203c7d1fe74
+        .quad   0x93c6aa2f38c85a30
+        .quad   0x76297d1f3d75a78a
+        .quad   0x2b7ef3d38ec8308c
+        .quad   0x828fd7ec71eb94ab
+        .quad   0x807c3b36c5062abd
+        .quad   0x0cb64cb831a94141
+        .quad   0x3030fc33534c6378
+        .quad   0xb9635c5ce541e861
+        .quad   0x15d9a9bed9b2c728
+        .quad   0x49233ea3f3775dcb
+
+        // 2^164 * 7 * G
+
+        .quad   0x629398fa8dbffc3a
+        .quad   0xe12fe52dd54db455
+        .quad   0xf3be11dfdaf25295
+        .quad   0x628b140dce5e7b51
+        .quad   0x7b3985fe1c9f249b
+        .quad   0x4fd6b2d5a1233293
+        .quad   0xceb345941adf4d62
+        .quad   0x6987ff6f542de50c
+        .quad   0x47e241428f83753c
+        .quad   0x6317bebc866af997
+        .quad   0xdabb5b433d1a9829
+        .quad   0x074d8d245287fb2d
+
+        // 2^164 * 8 * G
+
+        .quad   0x8337d9cd440bfc31
+        .quad   0x729d2ca1af318fd7
+        .quad   0xa040a4a4772c2070
+        .quad   0x46002ef03a7349be
+        .quad   0x481875c6c0e31488
+        .quad   0x219429b2e22034b4
+        .quad   0x7223c98a31283b65
+        .quad   0x3420d60b342277f9
+        .quad   0xfaa23adeaffe65f7
+        .quad   0x78261ed45be0764c
+        .quad   0x441c0a1e2f164403
+        .quad   0x5aea8e567a87d395
+
+        // 2^168 * 1 * G
+
+        .quad   0x7813c1a2bca4283d
+        .quad   0xed62f091a1863dd9
+        .quad   0xaec7bcb8c268fa86
+        .quad   0x10e5d3b76f1cae4c
+        .quad   0x2dbc6fb6e4e0f177
+        .quad   0x04e1bf29a4bd6a93
+        .quad   0x5e1966d4787af6e8
+        .quad   0x0edc5f5eb426d060
+        .quad   0x5453bfd653da8e67
+        .quad   0xe9dc1eec24a9f641
+        .quad   0xbf87263b03578a23
+        .quad   0x45b46c51361cba72
+
+        // 2^168 * 2 * G
+
+        .quad   0xa9402abf314f7fa1
+        .quad   0xe257f1dc8e8cf450
+        .quad   0x1dbbd54b23a8be84
+        .quad   0x2177bfa36dcb713b
+        .quad   0xce9d4ddd8a7fe3e4
+        .quad   0xab13645676620e30
+        .quad   0x4b594f7bb30e9958
+        .quad   0x5c1c0aef321229df
+        .quad   0x37081bbcfa79db8f
+        .quad   0x6048811ec25f59b3
+        .quad   0x087a76659c832487
+        .quad   0x4ae619387d8ab5bb
+
+        // 2^168 * 3 * G
+
+        .quad   0x8ddbf6aa5344a32e
+        .quad   0x7d88eab4b41b4078
+        .quad   0x5eb0eb974a130d60
+        .quad   0x1a00d91b17bf3e03
+        .quad   0x61117e44985bfb83
+        .quad   0xfce0462a71963136
+        .quad   0x83ac3448d425904b
+        .quad   0x75685abe5ba43d64
+        .quad   0x6e960933eb61f2b2
+        .quad   0x543d0fa8c9ff4952
+        .quad   0xdf7275107af66569
+        .quad   0x135529b623b0e6aa
+
+        // 2^168 * 4 * G
+
+        .quad   0x18f0dbd7add1d518
+        .quad   0x979f7888cfc11f11
+        .quad   0x8732e1f07114759b
+        .quad   0x79b5b81a65ca3a01
+        .quad   0xf5c716bce22e83fe
+        .quad   0xb42beb19e80985c1
+        .quad   0xec9da63714254aae
+        .quad   0x5972ea051590a613
+        .quad   0x0fd4ac20dc8f7811
+        .quad   0x9a9ad294ac4d4fa8
+        .quad   0xc01b2d64b3360434
+        .quad   0x4f7e9c95905f3bdb
+
+        // 2^168 * 5 * G
+
+        .quad   0x62674bbc5781302e
+        .quad   0xd8520f3989addc0f
+        .quad   0x8c2999ae53fbd9c6
+        .quad   0x31993ad92e638e4c
+        .quad   0x71c8443d355299fe
+        .quad   0x8bcd3b1cdbebead7
+        .quad   0x8092499ef1a49466
+        .quad   0x1942eec4a144adc8
+        .quad   0x7dac5319ae234992
+        .quad   0x2c1b3d910cea3e92
+        .quad   0x553ce494253c1122
+        .quad   0x2a0a65314ef9ca75
+
+        // 2^168 * 6 * G
+
+        .quad   0x2db7937ff7f927c2
+        .quad   0xdb741f0617d0a635
+        .quad   0x5982f3a21155af76
+        .quad   0x4cf6e218647c2ded
+        .quad   0xcf361acd3c1c793a
+        .quad   0x2f9ebcac5a35bc3b
+        .quad   0x60e860e9a8cda6ab
+        .quad   0x055dc39b6dea1a13
+        .quad   0xb119227cc28d5bb6
+        .quad   0x07e24ebc774dffab
+        .quad   0xa83c78cee4a32c89
+        .quad   0x121a307710aa24b6
+
+        // 2^168 * 7 * G
+
+        .quad   0xe4db5d5e9f034a97
+        .quad   0xe153fc093034bc2d
+        .quad   0x460546919551d3b1
+        .quad   0x333fc76c7a40e52d
+        .quad   0xd659713ec77483c9
+        .quad   0x88bfe077b82b96af
+        .quad   0x289e28231097bcd3
+        .quad   0x527bb94a6ced3a9b
+        .quad   0x563d992a995b482e
+        .quad   0x3405d07c6e383801
+        .quad   0x485035de2f64d8e5
+        .quad   0x6b89069b20a7a9f7
+
+        // 2^168 * 8 * G
+
+        .quad   0x812aa0416270220d
+        .quad   0x995a89faf9245b4e
+        .quad   0xffadc4ce5072ef05
+        .quad   0x23bc2103aa73eb73
+        .quad   0x4082fa8cb5c7db77
+        .quad   0x068686f8c734c155
+        .quad   0x29e6c8d9f6e7a57e
+        .quad   0x0473d308a7639bcf
+        .quad   0xcaee792603589e05
+        .quad   0x2b4b421246dcc492
+        .quad   0x02a1ef74e601a94f
+        .quad   0x102f73bfde04341a
+
+        // 2^172 * 1 * G
+
+        .quad   0xb5a2d50c7ec20d3e
+        .quad   0xc64bdd6ea0c97263
+        .quad   0x56e89052c1ff734d
+        .quad   0x4929c6f72b2ffaba
+        .quad   0x358ecba293a36247
+        .quad   0xaf8f9862b268fd65
+        .quad   0x412f7e9968a01c89
+        .quad   0x5786f312cd754524
+        .quad   0x337788ffca14032c
+        .quad   0xf3921028447f1ee3
+        .quad   0x8b14071f231bccad
+        .quad   0x4c817b4bf2344783
+
+        // 2^172 * 2 * G
+
+        .quad   0x0ff853852871b96e
+        .quad   0xe13e9fab60c3f1bb
+        .quad   0xeefd595325344402
+        .quad   0x0a37c37075b7744b
+        .quad   0x413ba057a40b4484
+        .quad   0xba4c2e1a4f5f6a43
+        .quad   0x614ba0a5aee1d61c
+        .quad   0x78a1531a8b05dc53
+        .quad   0x6cbdf1703ad0562b
+        .quad   0x8ecf4830c92521a3
+        .quad   0xdaebd303fd8424e7
+        .quad   0x72ad82a42e5ec56f
+
+        // 2^172 * 3 * G
+
+        .quad   0x3f9e8e35bafb65f6
+        .quad   0x39d69ec8f27293a1
+        .quad   0x6cb8cd958cf6a3d0
+        .quad   0x1734778173adae6d
+        .quad   0xc368939167024bc3
+        .quad   0x8e69d16d49502fda
+        .quad   0xfcf2ec3ce45f4b29
+        .quad   0x065f669ea3b4cbc4
+        .quad   0x8a00aec75532db4d
+        .quad   0xb869a4e443e31bb1
+        .quad   0x4a0f8552d3a7f515
+        .quad   0x19adeb7c303d7c08
+
+        // 2^172 * 4 * G
+
+        .quad   0xc720cb6153ead9a3
+        .quad   0x55b2c97f512b636e
+        .quad   0xb1e35b5fd40290b1
+        .quad   0x2fd9ccf13b530ee2
+        .quad   0x9d05ba7d43c31794
+        .quad   0x2470c8ff93322526
+        .quad   0x8323dec816197438
+        .quad   0x2852709881569b53
+        .quad   0x07bd475b47f796b8
+        .quad   0xd2c7b013542c8f54
+        .quad   0x2dbd23f43b24f87e
+        .quad   0x6551afd77b0901d6
+
+        // 2^172 * 5 * G
+
+        .quad   0x4546baaf54aac27f
+        .quad   0xf6f66fecb2a45a28
+        .quad   0x582d1b5b562bcfe8
+        .quad   0x44b123f3920f785f
+        .quad   0x68a24ce3a1d5c9ac
+        .quad   0xbb77a33d10ff6461
+        .quad   0x0f86ce4425d3166e
+        .quad   0x56507c0950b9623b
+        .quad   0x1206f0b7d1713e63
+        .quad   0x353fe3d915bafc74
+        .quad   0x194ceb970ad9d94d
+        .quad   0x62fadd7cf9d03ad3
+
+        // 2^172 * 6 * G
+
+        .quad   0xc6b5967b5598a074
+        .quad   0x5efe91ce8e493e25
+        .quad   0xd4b72c4549280888
+        .quad   0x20ef1149a26740c2
+        .quad   0x3cd7bc61e7ce4594
+        .quad   0xcd6b35a9b7dd267e
+        .quad   0xa080abc84366ef27
+        .quad   0x6ec7c46f59c79711
+        .quad   0x2f07ad636f09a8a2
+        .quad   0x8697e6ce24205e7d
+        .quad   0xc0aefc05ee35a139
+        .quad   0x15e80958b5f9d897
+
+        // 2^172 * 7 * G
+
+        .quad   0x25a5ef7d0c3e235b
+        .quad   0x6c39c17fbe134ee7
+        .quad   0xc774e1342dc5c327
+        .quad   0x021354b892021f39
+        .quad   0x4dd1ed355bb061c4
+        .quad   0x42dc0cef941c0700
+        .quad   0x61305dc1fd86340e
+        .quad   0x56b2cc930e55a443
+        .quad   0x1df79da6a6bfc5a2
+        .quad   0x02f3a2749fde4369
+        .quad   0xb323d9f2cda390a7
+        .quad   0x7be0847b8774d363
+
+        // 2^172 * 8 * G
+
+        .quad   0x8c99cc5a8b3f55c3
+        .quad   0x0611d7253fded2a0
+        .quad   0xed2995ff36b70a36
+        .quad   0x1f699a54d78a2619
+        .quad   0x1466f5af5307fa11
+        .quad   0x817fcc7ded6c0af2
+        .quad   0x0a6de44ec3a4a3fb
+        .quad   0x74071475bc927d0b
+        .quad   0xe77292f373e7ea8a
+        .quad   0x296537d2cb045a31
+        .quad   0x1bd0653ed3274fde
+        .quad   0x2f9a2c4476bd2966
+
+        // 2^176 * 1 * G
+
+        .quad   0xeb18b9ab7f5745c6
+        .quad   0x023a8aee5787c690
+        .quad   0xb72712da2df7afa9
+        .quad   0x36597d25ea5c013d
+        .quad   0xa2b4dae0b5511c9a
+        .quad   0x7ac860292bffff06
+        .quad   0x981f375df5504234
+        .quad   0x3f6bd725da4ea12d
+        .quad   0x734d8d7b106058ac
+        .quad   0xd940579e6fc6905f
+        .quad   0x6466f8f99202932d
+        .quad   0x7b7ecc19da60d6d0
+
+        // 2^176 * 2 * G
+
+        .quad   0x78c2373c695c690d
+        .quad   0xdd252e660642906e
+        .quad   0x951d44444ae12bd2
+        .quad   0x4235ad7601743956
+        .quad   0x6dae4a51a77cfa9b
+        .quad   0x82263654e7a38650
+        .quad   0x09bbffcd8f2d82db
+        .quad   0x03bedc661bf5caba
+        .quad   0x6258cb0d078975f5
+        .quad   0x492942549189f298
+        .quad   0xa0cab423e2e36ee4
+        .quad   0x0e7ce2b0cdf066a1
+
+        // 2^176 * 3 * G
+
+        .quad   0xc494643ac48c85a3
+        .quad   0xfd361df43c6139ad
+        .quad   0x09db17dd3ae94d48
+        .quad   0x666e0a5d8fb4674a
+        .quad   0xfea6fedfd94b70f9
+        .quad   0xf130c051c1fcba2d
+        .quad   0x4882d47e7f2fab89
+        .quad   0x615256138aeceeb5
+        .quad   0x2abbf64e4870cb0d
+        .quad   0xcd65bcf0aa458b6b
+        .quad   0x9abe4eba75e8985d
+        .quad   0x7f0bc810d514dee4
+
+        // 2^176 * 4 * G
+
+        .quad   0xb9006ba426f4136f
+        .quad   0x8d67369e57e03035
+        .quad   0xcbc8dfd94f463c28
+        .quad   0x0d1f8dbcf8eedbf5
+        .quad   0x83ac9dad737213a0
+        .quad   0x9ff6f8ba2ef72e98
+        .quad   0x311e2edd43ec6957
+        .quad   0x1d3a907ddec5ab75
+        .quad   0xba1693313ed081dc
+        .quad   0x29329fad851b3480
+        .quad   0x0128013c030321cb
+        .quad   0x00011b44a31bfde3
+
+        // 2^176 * 5 * G
+
+        .quad   0x3fdfa06c3fc66c0c
+        .quad   0x5d40e38e4dd60dd2
+        .quad   0x7ae38b38268e4d71
+        .quad   0x3ac48d916e8357e1
+        .quad   0x16561f696a0aa75c
+        .quad   0xc1bf725c5852bd6a
+        .quad   0x11a8dd7f9a7966ad
+        .quad   0x63d988a2d2851026
+        .quad   0x00120753afbd232e
+        .quad   0xe92bceb8fdd8f683
+        .quad   0xf81669b384e72b91
+        .quad   0x33fad52b2368a066
+
+        // 2^176 * 6 * G
+
+        .quad   0x540649c6c5e41e16
+        .quad   0x0af86430333f7735
+        .quad   0xb2acfcd2f305e746
+        .quad   0x16c0f429a256dca7
+        .quad   0x8d2cc8d0c422cfe8
+        .quad   0x072b4f7b05a13acb
+        .quad   0xa3feb6e6ecf6a56f
+        .quad   0x3cc355ccb90a71e2
+        .quad   0xe9b69443903e9131
+        .quad   0xb8a494cb7a5637ce
+        .quad   0xc87cd1a4baba9244
+        .quad   0x631eaf426bae7568
+
+        // 2^176 * 7 * G
+
+        .quad   0xb3e90410da66fe9f
+        .quad   0x85dd4b526c16e5a6
+        .quad   0xbc3d97611ef9bf83
+        .quad   0x5599648b1ea919b5
+        .quad   0x47d975b9a3700de8
+        .quad   0x7280c5fbe2f80552
+        .quad   0x53658f2732e45de1
+        .quad   0x431f2c7f665f80b5
+        .quad   0xd6026344858f7b19
+        .quad   0x14ab352fa1ea514a
+        .quad   0x8900441a2090a9d7
+        .quad   0x7b04715f91253b26
+
+        // 2^176 * 8 * G
+
+        .quad   0x83edbd28acf6ae43
+        .quad   0x86357c8b7d5c7ab4
+        .quad   0xc0404769b7eb2c44
+        .quad   0x59b37bf5c2f6583f
+        .quad   0xb376c280c4e6bac6
+        .quad   0x970ed3dd6d1d9b0b
+        .quad   0xb09a9558450bf944
+        .quad   0x48d0acfa57cde223
+        .quad   0xb60f26e47dabe671
+        .quad   0xf1d1a197622f3a37
+        .quad   0x4208ce7ee9960394
+        .quad   0x16234191336d3bdb
+
+        // 2^180 * 1 * G
+
+        .quad   0xf19aeac733a63aef
+        .quad   0x2c7fba5d4442454e
+        .quad   0x5da87aa04795e441
+        .quad   0x413051e1a4e0b0f5
+        .quad   0x852dd1fd3d578bbe
+        .quad   0x2b65ce72c3286108
+        .quad   0x658c07f4eace2273
+        .quad   0x0933f804ec38ab40
+        .quad   0xa7ab69798d496476
+        .quad   0x8121aadefcb5abc8
+        .quad   0xa5dc12ef7b539472
+        .quad   0x07fd47065e45351a
+
+        // 2^180 * 2 * G
+
+        .quad   0xc8583c3d258d2bcd
+        .quad   0x17029a4daf60b73f
+        .quad   0xfa0fc9d6416a3781
+        .quad   0x1c1e5fba38b3fb23
+        .quad   0x304211559ae8e7c3
+        .quad   0xf281b229944882a5
+        .quad   0x8a13ac2e378250e4
+        .quad   0x014afa0954ba48f4
+        .quad   0xcb3197001bb3666c
+        .quad   0x330060524bffecb9
+        .quad   0x293711991a88233c
+        .quad   0x291884363d4ed364
+
+        // 2^180 * 3 * G
+
+        .quad   0x033c6805dc4babfa
+        .quad   0x2c15bf5e5596ecc1
+        .quad   0x1bc70624b59b1d3b
+        .quad   0x3ede9850a19f0ec5
+        .quad   0xfb9d37c3bc1ab6eb
+        .quad   0x02be14534d57a240
+        .quad   0xf4d73415f8a5e1f6
+        .quad   0x5964f4300ccc8188
+        .quad   0xe44a23152d096800
+        .quad   0x5c08c55970866996
+        .quad   0xdf2db60a46affb6e
+        .quad   0x579155c1f856fd89
+
+        // 2^180 * 4 * G
+
+        .quad   0x96324edd12e0c9ef
+        .quad   0x468b878df2420297
+        .quad   0x199a3776a4f573be
+        .quad   0x1e7fbcf18e91e92a
+        .quad   0xb5f16b630817e7a6
+        .quad   0x808c69233c351026
+        .quad   0x324a983b54cef201
+        .quad   0x53c092084a485345
+        .quad   0xd2d41481f1cbafbf
+        .quad   0x231d2db6716174e5
+        .quad   0x0b7d7656e2a55c98
+        .quad   0x3e955cd82aa495f6
+
+        // 2^180 * 5 * G
+
+        .quad   0xe48f535e3ed15433
+        .quad   0xd075692a0d7270a3
+        .quad   0x40fbd21daade6387
+        .quad   0x14264887cf4495f5
+        .quad   0xab39f3ef61bb3a3f
+        .quad   0x8eb400652eb9193e
+        .quad   0xb5de6ecc38c11f74
+        .quad   0x654d7e9626f3c49f
+        .quad   0xe564cfdd5c7d2ceb
+        .quad   0x82eeafded737ccb9
+        .quad   0x6107db62d1f9b0ab
+        .quad   0x0b6baac3b4358dbb
+
+        // 2^180 * 6 * G
+
+        .quad   0x7ae62bcb8622fe98
+        .quad   0x47762256ceb891af
+        .quad   0x1a5a92bcf2e406b4
+        .quad   0x7d29401784e41501
+        .quad   0x204abad63700a93b
+        .quad   0xbe0023d3da779373
+        .quad   0xd85f0346633ab709
+        .quad   0x00496dc490820412
+        .quad   0x1c74b88dc27e6360
+        .quad   0x074854268d14850c
+        .quad   0xa145fb7b3e0dcb30
+        .quad   0x10843f1b43803b23
+
+        // 2^180 * 7 * G
+
+        .quad   0xc5f90455376276dd
+        .quad   0xce59158dd7645cd9
+        .quad   0x92f65d511d366b39
+        .quad   0x11574b6e526996c4
+        .quad   0xd56f672de324689b
+        .quad   0xd1da8aedb394a981
+        .quad   0xdd7b58fe9168cfed
+        .quad   0x7ce246cd4d56c1e8
+        .quad   0xb8f4308e7f80be53
+        .quad   0x5f3cb8cb34a9d397
+        .quad   0x18a961bd33cc2b2c
+        .quad   0x710045fb3a9af671
+
+        // 2^180 * 8 * G
+
+        .quad   0x73f93d36101b95eb
+        .quad   0xfaef33794f6f4486
+        .quad   0x5651735f8f15e562
+        .quad   0x7fa3f19058b40da1
+        .quad   0xa03fc862059d699e
+        .quad   0x2370cfa19a619e69
+        .quad   0xc4fe3b122f823deb
+        .quad   0x1d1b056fa7f0844e
+        .quad   0x1bc64631e56bf61f
+        .quad   0xd379ab106e5382a3
+        .quad   0x4d58c57e0540168d
+        .quad   0x566256628442d8e4
+
+        // 2^184 * 1 * G
+
+        .quad   0xb9e499def6267ff6
+        .quad   0x7772ca7b742c0843
+        .quad   0x23a0153fe9a4f2b1
+        .quad   0x2cdfdfecd5d05006
+        .quad   0xdd499cd61ff38640
+        .quad   0x29cd9bc3063625a0
+        .quad   0x51e2d8023dd73dc3
+        .quad   0x4a25707a203b9231
+        .quad   0x2ab7668a53f6ed6a
+        .quad   0x304242581dd170a1
+        .quad   0x4000144c3ae20161
+        .quad   0x5721896d248e49fc
+
+        // 2^184 * 2 * G
+
+        .quad   0x0b6e5517fd181bae
+        .quad   0x9022629f2bb963b4
+        .quad   0x5509bce932064625
+        .quad   0x578edd74f63c13da
+        .quad   0x285d5091a1d0da4e
+        .quad   0x4baa6fa7b5fe3e08
+        .quad   0x63e5177ce19393b3
+        .quad   0x03c935afc4b030fd
+        .quad   0x997276c6492b0c3d
+        .quad   0x47ccc2c4dfe205fc
+        .quad   0xdcd29b84dd623a3c
+        .quad   0x3ec2ab590288c7a2
+
+        // 2^184 * 3 * G
+
+        .quad   0xa1a0d27be4d87bb9
+        .quad   0xa98b4deb61391aed
+        .quad   0x99a0ddd073cb9b83
+        .quad   0x2dd5c25a200fcace
+        .quad   0xa7213a09ae32d1cb
+        .quad   0x0f2b87df40f5c2d5
+        .quad   0x0baea4c6e81eab29
+        .quad   0x0e1bf66c6adbac5e
+        .quad   0xe2abd5e9792c887e
+        .quad   0x1a020018cb926d5d
+        .quad   0xbfba69cdbaae5f1e
+        .quad   0x730548b35ae88f5f
+
+        // 2^184 * 4 * G
+
+        .quad   0xc43551a3cba8b8ee
+        .quad   0x65a26f1db2115f16
+        .quad   0x760f4f52ab8c3850
+        .quad   0x3043443b411db8ca
+        .quad   0x805b094ba1d6e334
+        .quad   0xbf3ef17709353f19
+        .quad   0x423f06cb0622702b
+        .quad   0x585a2277d87845dd
+        .quad   0xa18a5f8233d48962
+        .quad   0x6698c4b5ec78257f
+        .quad   0xa78e6fa5373e41ff
+        .quad   0x7656278950ef981f
+
+        // 2^184 * 5 * G
+
+        .quad   0x38c3cf59d51fc8c0
+        .quad   0x9bedd2fd0506b6f2
+        .quad   0x26bf109fab570e8f
+        .quad   0x3f4160a8c1b846a6
+        .quad   0xe17073a3ea86cf9d
+        .quad   0x3a8cfbb707155fdc
+        .quad   0x4853e7fc31838a8e
+        .quad   0x28bbf484b613f616
+        .quad   0xf2612f5c6f136c7c
+        .quad   0xafead107f6dd11be
+        .quad   0x527e9ad213de6f33
+        .quad   0x1e79cb358188f75d
+
+        // 2^184 * 6 * G
+
+        .quad   0x013436c3eef7e3f1
+        .quad   0x828b6a7ffe9e10f8
+        .quad   0x7ff908e5bcf9defc
+        .quad   0x65d7951b3a3b3831
+        .quad   0x77e953d8f5e08181
+        .quad   0x84a50c44299dded9
+        .quad   0xdc6c2d0c864525e5
+        .quad   0x478ab52d39d1f2f4
+        .quad   0x66a6a4d39252d159
+        .quad   0xe5dde1bc871ac807
+        .quad   0xb82c6b40a6c1c96f
+        .quad   0x16d87a411a212214
+
+        // 2^184 * 7 * G
+
+        .quad   0xb3bd7e5a42066215
+        .quad   0x879be3cd0c5a24c1
+        .quad   0x57c05db1d6f994b7
+        .quad   0x28f87c8165f38ca6
+        .quad   0xfba4d5e2d54e0583
+        .quad   0xe21fafd72ebd99fa
+        .quad   0x497ac2736ee9778f
+        .quad   0x1f990b577a5a6dde
+        .quad   0xa3344ead1be8f7d6
+        .quad   0x7d1e50ebacea798f
+        .quad   0x77c6569e520de052
+        .quad   0x45882fe1534d6d3e
+
+        // 2^184 * 8 * G
+
+        .quad   0x6669345d757983d6
+        .quad   0x62b6ed1117aa11a6
+        .quad   0x7ddd1857985e128f
+        .quad   0x688fe5b8f626f6dd
+        .quad   0xd8ac9929943c6fe4
+        .quad   0xb5f9f161a38392a2
+        .quad   0x2699db13bec89af3
+        .quad   0x7dcf843ce405f074
+        .quad   0x6c90d6484a4732c0
+        .quad   0xd52143fdca563299
+        .quad   0xb3be28c3915dc6e1
+        .quad   0x6739687e7327191b
+
+        // 2^188 * 1 * G
+
+        .quad   0x9f65c5ea200814cf
+        .quad   0x840536e169a31740
+        .quad   0x8b0ed13925c8b4ad
+        .quad   0x0080dbafe936361d
+        .quad   0x8ce5aad0c9cb971f
+        .quad   0x1156aaa99fd54a29
+        .quad   0x41f7247015af9b78
+        .quad   0x1fe8cca8420f49aa
+        .quad   0x72a1848f3c0cc82a
+        .quad   0x38c560c2877c9e54
+        .quad   0x5004e228ce554140
+        .quad   0x042418a103429d71
+
+        // 2^188 * 2 * G
+
+        .quad   0x899dea51abf3ff5f
+        .quad   0x9b93a8672fc2d8ba
+        .quad   0x2c38cb97be6ebd5c
+        .quad   0x114d578497263b5d
+        .quad   0x58e84c6f20816247
+        .quad   0x8db2b2b6e36fd793
+        .quad   0x977182561d484d85
+        .quad   0x0822024f8632abd7
+        .quad   0xb301bb7c6b1beca3
+        .quad   0x55393f6dc6eb1375
+        .quad   0x910d281097b6e4eb
+        .quad   0x1ad4548d9d479ea3
+
+        // 2^188 * 3 * G
+
+        .quad   0xcd5a7da0389a48fd
+        .quad   0xb38fa4aa9a78371e
+        .quad   0xc6d9761b2cdb8e6c
+        .quad   0x35cf51dbc97e1443
+        .quad   0xa06fe66d0fe9fed3
+        .quad   0xa8733a401c587909
+        .quad   0x30d14d800df98953
+        .quad   0x41ce5876c7b30258
+        .quad   0x59ac3bc5d670c022
+        .quad   0xeae67c109b119406
+        .quad   0x9798bdf0b3782fda
+        .quad   0x651e3201fd074092
+
+        // 2^188 * 4 * G
+
+        .quad   0xd63d8483ef30c5cf
+        .quad   0x4cd4b4962361cc0c
+        .quad   0xee90e500a48426ac
+        .quad   0x0af51d7d18c14eeb
+        .quad   0xa57ba4a01efcae9e
+        .quad   0x769f4beedc308a94
+        .quad   0xd1f10eeb3603cb2e
+        .quad   0x4099ce5e7e441278
+        .quad   0x1ac98e4f8a5121e9
+        .quad   0x7dae9544dbfa2fe0
+        .quad   0x8320aa0dd6430df9
+        .quad   0x667282652c4a2fb5
+
+        // 2^188 * 5 * G
+
+        .quad   0x874621f4d86bc9ab
+        .quad   0xb54c7bbe56fe6fea
+        .quad   0x077a24257fadc22c
+        .quad   0x1ab53be419b90d39
+        .quad   0xada8b6e02946db23
+        .quad   0x1c0ce51a7b253ab7
+        .quad   0x8448c85a66dd485b
+        .quad   0x7f1fc025d0675adf
+        .quad   0xd8ee1b18319ea6aa
+        .quad   0x004d88083a21f0da
+        .quad   0x3bd6aa1d883a4f4b
+        .quad   0x4db9a3a6dfd9fd14
+
+        // 2^188 * 6 * G
+
+        .quad   0x8ce7b23bb99c0755
+        .quad   0x35c5d6edc4f50f7a
+        .quad   0x7e1e2ed2ed9b50c3
+        .quad   0x36305f16e8934da1
+        .quad   0xd95b00bbcbb77c68
+        .quad   0xddbc846a91f17849
+        .quad   0x7cf700aebe28d9b3
+        .quad   0x5ce1285c85d31f3e
+        .quad   0x31b6972d98b0bde8
+        .quad   0x7d920706aca6de5b
+        .quad   0xe67310f8908a659f
+        .quad   0x50fac2a6efdf0235
+
+        // 2^188 * 7 * G
+
+        .quad   0xf3d3a9f35b880f5a
+        .quad   0xedec050cdb03e7c2
+        .quad   0xa896981ff9f0b1a2
+        .quad   0x49a4ae2bac5e34a4
+        .quad   0x295b1c86f6f449bc
+        .quad   0x51b2e84a1f0ab4dd
+        .quad   0xc001cb30aa8e551d
+        .quad   0x6a28d35944f43662
+        .quad   0x28bb12ee04a740e0
+        .quad   0x14313bbd9bce8174
+        .quad   0x72f5b5e4e8c10c40
+        .quad   0x7cbfb19936adcd5b
+
+        // 2^188 * 8 * G
+
+        .quad   0xa311ddc26b89792d
+        .quad   0x1b30b4c6da512664
+        .quad   0x0ca77b4ccf150859
+        .quad   0x1de443df1b009408
+        .quad   0x8e793a7acc36e6e0
+        .quad   0xf9fab7a37d586eed
+        .quad   0x3a4f9692bae1f4e4
+        .quad   0x1c14b03eff5f447e
+        .quad   0x19647bd114a85291
+        .quad   0x57b76cb21034d3af
+        .quad   0x6329db440f9d6dfa
+        .quad   0x5ef43e586a571493
+
+        // 2^192 * 1 * G
+
+        .quad   0xef782014385675a6
+        .quad   0xa2649f30aafda9e8
+        .quad   0x4cd1eb505cdfa8cb
+        .quad   0x46115aba1d4dc0b3
+        .quad   0xa66dcc9dc80c1ac0
+        .quad   0x97a05cf41b38a436
+        .quad   0xa7ebf3be95dbd7c6
+        .quad   0x7da0b8f68d7e7dab
+        .quad   0xd40f1953c3b5da76
+        .quad   0x1dac6f7321119e9b
+        .quad   0x03cc6021feb25960
+        .quad   0x5a5f887e83674b4b
+
+        // 2^192 * 2 * G
+
+        .quad   0x8f6301cf70a13d11
+        .quad   0xcfceb815350dd0c4
+        .quad   0xf70297d4a4bca47e
+        .quad   0x3669b656e44d1434
+        .quad   0x9e9628d3a0a643b9
+        .quad   0xb5c3cb00e6c32064
+        .quad   0x9b5302897c2dec32
+        .quad   0x43e37ae2d5d1c70c
+        .quad   0x387e3f06eda6e133
+        .quad   0x67301d5199a13ac0
+        .quad   0xbd5ad8f836263811
+        .quad   0x6a21e6cd4fd5e9be
+
+        // 2^192 * 3 * G
+
+        .quad   0xf1c6170a3046e65f
+        .quad   0x58712a2a00d23524
+        .quad   0x69dbbd3c8c82b755
+        .quad   0x586bf9f1a195ff57
+        .quad   0xef4129126699b2e3
+        .quad   0x71d30847708d1301
+        .quad   0x325432d01182b0bd
+        .quad   0x45371b07001e8b36
+        .quad   0xa6db088d5ef8790b
+        .quad   0x5278f0dc610937e5
+        .quad   0xac0349d261a16eb8
+        .quad   0x0eafb03790e52179
+
+        // 2^192 * 4 * G
+
+        .quad   0x960555c13748042f
+        .quad   0x219a41e6820baa11
+        .quad   0x1c81f73873486d0c
+        .quad   0x309acc675a02c661
+        .quad   0x5140805e0f75ae1d
+        .quad   0xec02fbe32662cc30
+        .quad   0x2cebdf1eea92396d
+        .quad   0x44ae3344c5435bb3
+        .quad   0x9cf289b9bba543ee
+        .quad   0xf3760e9d5ac97142
+        .quad   0x1d82e5c64f9360aa
+        .quad   0x62d5221b7f94678f
+
+        // 2^192 * 5 * G
+
+        .quad   0x524c299c18d0936d
+        .quad   0xc86bb56c8a0c1a0c
+        .quad   0xa375052edb4a8631
+        .quad   0x5c0efde4bc754562
+        .quad   0x7585d4263af77a3c
+        .quad   0xdfae7b11fee9144d
+        .quad   0xa506708059f7193d
+        .quad   0x14f29a5383922037
+        .quad   0xdf717edc25b2d7f5
+        .quad   0x21f970db99b53040
+        .quad   0xda9234b7c3ed4c62
+        .quad   0x5e72365c7bee093e
+
+        // 2^192 * 6 * G
+
+        .quad   0x575bfc074571217f
+        .quad   0x3779675d0694d95b
+        .quad   0x9a0a37bbf4191e33
+        .quad   0x77f1104c47b4eabc
+        .quad   0x7d9339062f08b33e
+        .quad   0x5b9659e5df9f32be
+        .quad   0xacff3dad1f9ebdfd
+        .quad   0x70b20555cb7349b7
+        .quad   0xbe5113c555112c4c
+        .quad   0x6688423a9a881fcd
+        .quad   0x446677855e503b47
+        .quad   0x0e34398f4a06404a
+
+        // 2^192 * 7 * G
+
+        .quad   0xb67d22d93ecebde8
+        .quad   0x09b3e84127822f07
+        .quad   0x743fa61fb05b6d8d
+        .quad   0x5e5405368a362372
+        .quad   0x18930b093e4b1928
+        .quad   0x7de3e10e73f3f640
+        .quad   0xf43217da73395d6f
+        .quad   0x6f8aded6ca379c3e
+        .quad   0xe340123dfdb7b29a
+        .quad   0x487b97e1a21ab291
+        .quad   0xf9967d02fde6949e
+        .quad   0x780de72ec8d3de97
+
+        // 2^192 * 8 * G
+
+        .quad   0x0ae28545089ae7bc
+        .quad   0x388ddecf1c7f4d06
+        .quad   0x38ac15510a4811b8
+        .quad   0x0eb28bf671928ce4
+        .quad   0x671feaf300f42772
+        .quad   0x8f72eb2a2a8c41aa
+        .quad   0x29a17fd797373292
+        .quad   0x1defc6ad32b587a6
+        .quad   0xaf5bbe1aef5195a7
+        .quad   0x148c1277917b15ed
+        .quad   0x2991f7fb7ae5da2e
+        .quad   0x467d201bf8dd2867
+
+        // 2^196 * 1 * G
+
+        .quad   0x7906ee72f7bd2e6b
+        .quad   0x05d270d6109abf4e
+        .quad   0x8d5cfe45b941a8a4
+        .quad   0x44c218671c974287
+        .quad   0x745f9d56296bc318
+        .quad   0x993580d4d8152e65
+        .quad   0xb0e5b13f5839e9ce
+        .quad   0x51fc2b28d43921c0
+        .quad   0x1b8fd11795e2a98c
+        .quad   0x1c4e5ee12b6b6291
+        .quad   0x5b30e7107424b572
+        .quad   0x6e6b9de84c4f4ac6
+
+        // 2^196 * 2 * G
+
+        .quad   0xdff25fce4b1de151
+        .quad   0xd841c0c7e11c4025
+        .quad   0x2554b3c854749c87
+        .quad   0x2d292459908e0df9
+        .quad   0x6b7c5f10f80cb088
+        .quad   0x736b54dc56e42151
+        .quad   0xc2b620a5c6ef99c4
+        .quad   0x5f4c802cc3a06f42
+        .quad   0x9b65c8f17d0752da
+        .quad   0x881ce338c77ee800
+        .quad   0xc3b514f05b62f9e3
+        .quad   0x66ed5dd5bec10d48
+
+        // 2^196 * 3 * G
+
+        .quad   0x7d38a1c20bb2089d
+        .quad   0x808334e196ccd412
+        .quad   0xc4a70b8c6c97d313
+        .quad   0x2eacf8bc03007f20
+        .quad   0xf0adf3c9cbca047d
+        .quad   0x81c3b2cbf4552f6b
+        .quad   0xcfda112d44735f93
+        .quad   0x1f23a0c77e20048c
+        .quad   0xf235467be5bc1570
+        .quad   0x03d2d9020dbab38c
+        .quad   0x27529aa2fcf9e09e
+        .quad   0x0840bef29d34bc50
+
+        // 2^196 * 4 * G
+
+        .quad   0x796dfb35dc10b287
+        .quad   0x27176bcd5c7ff29d
+        .quad   0x7f3d43e8c7b24905
+        .quad   0x0304f5a191c54276
+        .quad   0xcd54e06b7f37e4eb
+        .quad   0x8cc15f87f5e96cca
+        .quad   0xb8248bb0d3597dce
+        .quad   0x246affa06074400c
+        .quad   0x37d88e68fbe45321
+        .quad   0x86097548c0d75032
+        .quad   0x4e9b13ef894a0d35
+        .quad   0x25a83cac5753d325
+
+        // 2^196 * 5 * G
+
+        .quad   0x10222f48eed8165e
+        .quad   0x623fc1234b8bcf3a
+        .quad   0x1e145c09c221e8f0
+        .quad   0x7ccfa59fca782630
+        .quad   0x9f0f66293952b6e2
+        .quad   0x33db5e0e0934267b
+        .quad   0xff45252bd609fedc
+        .quad   0x06be10f5c506e0c9
+        .quad   0x1a9615a9b62a345f
+        .quad   0x22050c564a52fecc
+        .quad   0xa7a2788528bc0dfe
+        .quad   0x5e82770a1a1ee71d
+
+        // 2^196 * 6 * G
+
+        .quad   0x35425183ad896a5c
+        .quad   0xe8673afbe78d52f6
+        .quad   0x2c66f25f92a35f64
+        .quad   0x09d04f3b3b86b102
+        .quad   0xe802e80a42339c74
+        .quad   0x34175166a7fffae5
+        .quad   0x34865d1f1c408cae
+        .quad   0x2cca982c605bc5ee
+        .quad   0xfd2d5d35197dbe6e
+        .quad   0x207c2eea8be4ffa3
+        .quad   0x2613d8db325ae918
+        .quad   0x7a325d1727741d3e
+
+        // 2^196 * 7 * G
+
+        .quad   0xd036b9bbd16dfde2
+        .quad   0xa2055757c497a829
+        .quad   0x8e6cc966a7f12667
+        .quad   0x4d3b1a791239c180
+        .quad   0xecd27d017e2a076a
+        .quad   0xd788689f1636495e
+        .quad   0x52a61af0919233e5
+        .quad   0x2a479df17bb1ae64
+        .quad   0x9e5eee8e33db2710
+        .quad   0x189854ded6c43ca5
+        .quad   0xa41c22c592718138
+        .quad   0x27ad5538a43a5e9b
+
+        // 2^196 * 8 * G
+
+        .quad   0x2746dd4b15350d61
+        .quad   0xd03fcbc8ee9521b7
+        .quad   0xe86e365a138672ca
+        .quad   0x510e987f7e7d89e2
+        .quad   0xcb5a7d638e47077c
+        .quad   0x8db7536120a1c059
+        .quad   0x549e1e4d8bedfdcc
+        .quad   0x080153b7503b179d
+        .quad   0xdda69d930a3ed3e3
+        .quad   0x3d386ef1cd60a722
+        .quad   0xc817ad58bdaa4ee6
+        .quad   0x23be8d554fe7372a
+
+        // 2^200 * 1 * G
+
+        .quad   0x95fe919a74ef4fad
+        .quad   0x3a827becf6a308a2
+        .quad   0x964e01d309a47b01
+        .quad   0x71c43c4f5ba3c797
+        .quad   0xbc1ef4bd567ae7a9
+        .quad   0x3f624cb2d64498bd
+        .quad   0xe41064d22c1f4ec8
+        .quad   0x2ef9c5a5ba384001
+        .quad   0xb6fd6df6fa9e74cd
+        .quad   0xf18278bce4af267a
+        .quad   0x8255b3d0f1ef990e
+        .quad   0x5a758ca390c5f293
+
+        // 2^200 * 2 * G
+
+        .quad   0xa2b72710d9462495
+        .quad   0x3aa8c6d2d57d5003
+        .quad   0xe3d400bfa0b487ca
+        .quad   0x2dbae244b3eb72ec
+        .quad   0x8ce0918b1d61dc94
+        .quad   0x8ded36469a813066
+        .quad   0xd4e6a829afe8aad3
+        .quad   0x0a738027f639d43f
+        .quad   0x980f4a2f57ffe1cc
+        .quad   0x00670d0de1839843
+        .quad   0x105c3f4a49fb15fd
+        .quad   0x2698ca635126a69c
+
+        // 2^200 * 3 * G
+
+        .quad   0xe765318832b0ba78
+        .quad   0x381831f7925cff8b
+        .quad   0x08a81b91a0291fcc
+        .quad   0x1fb43dcc49caeb07
+        .quad   0x2e3d702f5e3dd90e
+        .quad   0x9e3f0918e4d25386
+        .quad   0x5e773ef6024da96a
+        .quad   0x3c004b0c4afa3332
+        .quad   0x9aa946ac06f4b82b
+        .quad   0x1ca284a5a806c4f3
+        .quad   0x3ed3265fc6cd4787
+        .quad   0x6b43fd01cd1fd217
+
+        // 2^200 * 4 * G
+
+        .quad   0xc7a75d4b4697c544
+        .quad   0x15fdf848df0fffbf
+        .quad   0x2868b9ebaa46785a
+        .quad   0x5a68d7105b52f714
+        .quad   0xb5c742583e760ef3
+        .quad   0x75dc52b9ee0ab990
+        .quad   0xbf1427c2072b923f
+        .quad   0x73420b2d6ff0d9f0
+        .quad   0xaf2cf6cb9e851e06
+        .quad   0x8f593913c62238c4
+        .quad   0xda8ab89699fbf373
+        .quad   0x3db5632fea34bc9e
+
+        // 2^200 * 5 * G
+
+        .quad   0xf46eee2bf75dd9d8
+        .quad   0x0d17b1f6396759a5
+        .quad   0x1bf2d131499e7273
+        .quad   0x04321adf49d75f13
+        .quad   0x2e4990b1829825d5
+        .quad   0xedeaeb873e9a8991
+        .quad   0xeef03d394c704af8
+        .quad   0x59197ea495df2b0e
+        .quad   0x04e16019e4e55aae
+        .quad   0xe77b437a7e2f92e9
+        .quad   0xc7ce2dc16f159aa4
+        .quad   0x45eafdc1f4d70cc0
+
+        // 2^200 * 6 * G
+
+        .quad   0x698401858045d72b
+        .quad   0x4c22faa2cf2f0651
+        .quad   0x941a36656b222dc6
+        .quad   0x5a5eebc80362dade
+        .quad   0xb60e4624cfccb1ed
+        .quad   0x59dbc292bd5c0395
+        .quad   0x31a09d1ddc0481c9
+        .quad   0x3f73ceea5d56d940
+        .quad   0xb7a7bfd10a4e8dc6
+        .quad   0xbe57007e44c9b339
+        .quad   0x60c1207f1557aefa
+        .quad   0x26058891266218db
+
+        // 2^200 * 7 * G
+
+        .quad   0x59f704a68360ff04
+        .quad   0xc3d93fde7661e6f4
+        .quad   0x831b2a7312873551
+        .quad   0x54ad0c2e4e615d57
+        .quad   0x4c818e3cc676e542
+        .quad   0x5e422c9303ceccad
+        .quad   0xec07cccab4129f08
+        .quad   0x0dedfa10b24443b8
+        .quad   0xee3b67d5b82b522a
+        .quad   0x36f163469fa5c1eb
+        .quad   0xa5b4d2f26ec19fd3
+        .quad   0x62ecb2baa77a9408
+
+        // 2^200 * 8 * G
+
+        .quad   0xe5ed795261152b3d
+        .quad   0x4962357d0eddd7d1
+        .quad   0x7482c8d0b96b4c71
+        .quad   0x2e59f919a966d8be
+        .quad   0x92072836afb62874
+        .quad   0x5fcd5e8579e104a5
+        .quad   0x5aad01adc630a14a
+        .quad   0x61913d5075663f98
+        .quad   0x0dc62d361a3231da
+        .quad   0xfa47583294200270
+        .quad   0x02d801513f9594ce
+        .quad   0x3ddbc2a131c05d5c
+
+        // 2^204 * 1 * G
+
+        .quad   0x3f50a50a4ffb81ef
+        .quad   0xb1e035093bf420bf
+        .quad   0x9baa8e1cc6aa2cd0
+        .quad   0x32239861fa237a40
+        .quad   0xfb735ac2004a35d1
+        .quad   0x31de0f433a6607c3
+        .quad   0x7b8591bfc528d599
+        .quad   0x55be9a25f5bb050c
+        .quad   0x0d005acd33db3dbf
+        .quad   0x0111b37c80ac35e2
+        .quad   0x4892d66c6f88ebeb
+        .quad   0x770eadb16508fbcd
+
+        // 2^204 * 2 * G
+
+        .quad   0x8451f9e05e4e89dd
+        .quad   0xc06302ffbc793937
+        .quad   0x5d22749556a6495c
+        .quad   0x09a6755ca05603fb
+        .quad   0xf1d3b681a05071b9
+        .quad   0x2207659a3592ff3a
+        .quad   0x5f0169297881e40e
+        .quad   0x16bedd0e86ba374e
+        .quad   0x5ecccc4f2c2737b5
+        .quad   0x43b79e0c2dccb703
+        .quad   0x33e008bc4ec43df3
+        .quad   0x06c1b840f07566c0
+
+        // 2^204 * 3 * G
+
+        .quad   0x7688a5c6a388f877
+        .quad   0x02a96c14deb2b6ac
+        .quad   0x64c9f3431b8c2af8
+        .quad   0x3628435554a1eed6
+        .quad   0x69ee9e7f9b02805c
+        .quad   0xcbff828a547d1640
+        .quad   0x3d93a869b2430968
+        .quad   0x46b7b8cd3fe26972
+        .quad   0xe9812086fe7eebe0
+        .quad   0x4cba6be72f515437
+        .quad   0x1d04168b516efae9
+        .quad   0x5ea1391043982cb9
+
+        // 2^204 * 4 * G
+
+        .quad   0x49125c9cf4702ee1
+        .quad   0x4520b71f8b25b32d
+        .quad   0x33193026501fef7e
+        .quad   0x656d8997c8d2eb2b
+        .quad   0x6f2b3be4d5d3b002
+        .quad   0xafec33d96a09c880
+        .quad   0x035f73a4a8bcc4cc
+        .quad   0x22c5b9284662198b
+        .quad   0xcb58c8fe433d8939
+        .quad   0x89a0cb2e6a8d7e50
+        .quad   0x79ca955309fbbe5a
+        .quad   0x0c626616cd7fc106
+
+        // 2^204 * 5 * G
+
+        .quad   0x1ffeb80a4879b61f
+        .quad   0x6396726e4ada21ed
+        .quad   0x33c7b093368025ba
+        .quad   0x471aa0c6f3c31788
+        .quad   0x8fdfc379fbf454b1
+        .quad   0x45a5a970f1a4b771
+        .quad   0xac921ef7bad35915
+        .quad   0x42d088dca81c2192
+        .quad   0x8fda0f37a0165199
+        .quad   0x0adadb77c8a0e343
+        .quad   0x20fbfdfcc875e820
+        .quad   0x1cf2bea80c2206e7
+
+        // 2^204 * 6 * G
+
+        .quad   0xc2ddf1deb36202ac
+        .quad   0x92a5fe09d2e27aa5
+        .quad   0x7d1648f6fc09f1d3
+        .quad   0x74c2cc0513bc4959
+        .quad   0x982d6e1a02c0412f
+        .quad   0x90fa4c83db58e8fe
+        .quad   0x01c2f5bcdcb18bc0
+        .quad   0x686e0c90216abc66
+        .quad   0x1fadbadba54395a7
+        .quad   0xb41a02a0ae0da66a
+        .quad   0xbf19f598bba37c07
+        .quad   0x6a12b8acde48430d
+
+        // 2^204 * 7 * G
+
+        .quad   0xf8daea1f39d495d9
+        .quad   0x592c190e525f1dfc
+        .quad   0xdb8cbd04c9991d1b
+        .quad   0x11f7fda3d88f0cb7
+        .quad   0x793bdd801aaeeb5f
+        .quad   0x00a2a0aac1518871
+        .quad   0xe8a373a31f2136b4
+        .quad   0x48aab888fc91ef19
+        .quad   0x041f7e925830f40e
+        .quad   0x002d6ca979661c06
+        .quad   0x86dc9ff92b046a2e
+        .quad   0x760360928b0493d1
+
+        // 2^204 * 8 * G
+
+        .quad   0x21bb41c6120cf9c6
+        .quad   0xeab2aa12decda59b
+        .quad   0xc1a72d020aa48b34
+        .quad   0x215d4d27e87d3b68
+        .quad   0xb43108e5695a0b05
+        .quad   0x6cb00ee8ad37a38b
+        .quad   0x5edad6eea3537381
+        .quad   0x3f2602d4b6dc3224
+        .quad   0xc8b247b65bcaf19c
+        .quad   0x49779dc3b1b2c652
+        .quad   0x89a180bbd5ece2e2
+        .quad   0x13f098a3cec8e039
+
+        // 2^208 * 1 * G
+
+        .quad   0x9adc0ff9ce5ec54b
+        .quad   0x039c2a6b8c2f130d
+        .quad   0x028007c7f0f89515
+        .quad   0x78968314ac04b36b
+        .quad   0xf3aa57a22796bb14
+        .quad   0x883abab79b07da21
+        .quad   0xe54be21831a0391c
+        .quad   0x5ee7fb38d83205f9
+        .quad   0x538dfdcb41446a8e
+        .quad   0xa5acfda9434937f9
+        .quad   0x46af908d263c8c78
+        .quad   0x61d0633c9bca0d09
+
+        // 2^208 * 2 * G
+
+        .quad   0x63744935ffdb2566
+        .quad   0xc5bd6b89780b68bb
+        .quad   0x6f1b3280553eec03
+        .quad   0x6e965fd847aed7f5
+        .quad   0xada328bcf8fc73df
+        .quad   0xee84695da6f037fc
+        .quad   0x637fb4db38c2a909
+        .quad   0x5b23ac2df8067bdc
+        .quad   0x9ad2b953ee80527b
+        .quad   0xe88f19aafade6d8d
+        .quad   0x0e711704150e82cf
+        .quad   0x79b9bbb9dd95dedc
+
+        // 2^208 * 3 * G
+
+        .quad   0xebb355406a3126c2
+        .quad   0xd26383a868c8c393
+        .quad   0x6c0c6429e5b97a82
+        .quad   0x5065f158c9fd2147
+        .quad   0xd1997dae8e9f7374
+        .quad   0xa032a2f8cfbb0816
+        .quad   0xcd6cba126d445f0a
+        .quad   0x1ba811460accb834
+        .quad   0x708169fb0c429954
+        .quad   0xe14600acd76ecf67
+        .quad   0x2eaab98a70e645ba
+        .quad   0x3981f39e58a4faf2
+
+        // 2^208 * 4 * G
+
+        .quad   0x18fb8a7559230a93
+        .quad   0x1d168f6960e6f45d
+        .quad   0x3a85a94514a93cb5
+        .quad   0x38dc083705acd0fd
+        .quad   0xc845dfa56de66fde
+        .quad   0xe152a5002c40483a
+        .quad   0xe9d2e163c7b4f632
+        .quad   0x30f4452edcbc1b65
+        .quad   0x856d2782c5759740
+        .quad   0xfa134569f99cbecc
+        .quad   0x8844fc73c0ea4e71
+        .quad   0x632d9a1a593f2469
+
+        // 2^208 * 5 * G
+
+        .quad   0xf6bb6b15b807cba6
+        .quad   0x1823c7dfbc54f0d7
+        .quad   0xbb1d97036e29670b
+        .quad   0x0b24f48847ed4a57
+        .quad   0xbf09fd11ed0c84a7
+        .quad   0x63f071810d9f693a
+        .quad   0x21908c2d57cf8779
+        .quad   0x3a5a7df28af64ba2
+        .quad   0xdcdad4be511beac7
+        .quad   0xa4538075ed26ccf2
+        .quad   0xe19cff9f005f9a65
+        .quad   0x34fcf74475481f63
+
+        // 2^208 * 6 * G
+
+        .quad   0xc197e04c789767ca
+        .quad   0xb8714dcb38d9467d
+        .quad   0x55de888283f95fa8
+        .quad   0x3d3bdc164dfa63f7
+        .quad   0xa5bb1dab78cfaa98
+        .quad   0x5ceda267190b72f2
+        .quad   0x9309c9110a92608e
+        .quad   0x0119a3042fb374b0
+        .quad   0x67a2d89ce8c2177d
+        .quad   0x669da5f66895d0c1
+        .quad   0xf56598e5b282a2b0
+        .quad   0x56c088f1ede20a73
+
+        // 2^208 * 7 * G
+
+        .quad   0x336d3d1110a86e17
+        .quad   0xd7f388320b75b2fa
+        .quad   0xf915337625072988
+        .quad   0x09674c6b99108b87
+        .quad   0x581b5fac24f38f02
+        .quad   0xa90be9febae30cbd
+        .quad   0x9a2169028acf92f0
+        .quad   0x038b7ea48359038f
+        .quad   0x9f4ef82199316ff8
+        .quad   0x2f49d282eaa78d4f
+        .quad   0x0971a5ab5aef3174
+        .quad   0x6e5e31025969eb65
+
+        // 2^208 * 8 * G
+
+        .quad   0xb16c62f587e593fb
+        .quad   0x4999eddeca5d3e71
+        .quad   0xb491c1e014cc3e6d
+        .quad   0x08f5114789a8dba8
+        .quad   0x3304fb0e63066222
+        .quad   0xfb35068987acba3f
+        .quad   0xbd1924778c1061a3
+        .quad   0x3058ad43d1838620
+        .quad   0x323c0ffde57663d0
+        .quad   0x05c3df38a22ea610
+        .quad   0xbdc78abdac994f9a
+        .quad   0x26549fa4efe3dc99
+
+        // 2^212 * 1 * G
+
+        .quad   0x738b38d787ce8f89
+        .quad   0xb62658e24179a88d
+        .quad   0x30738c9cf151316d
+        .quad   0x49128c7f727275c9
+        .quad   0x04dbbc17f75396b9
+        .quad   0x69e6a2d7d2f86746
+        .quad   0xc6409d99f53eabc6
+        .quad   0x606175f6332e25d2
+        .quad   0x4021370ef540e7dd
+        .quad   0x0910d6f5a1f1d0a5
+        .quad   0x4634aacd5b06b807
+        .quad   0x6a39e6356944f235
+
+        // 2^212 * 2 * G
+
+        .quad   0x96cd5640df90f3e7
+        .quad   0x6c3a760edbfa25ea
+        .quad   0x24f3ef0959e33cc4
+        .quad   0x42889e7e530d2e58
+        .quad   0x1da1965774049e9d
+        .quad   0xfbcd6ea198fe352b
+        .quad   0xb1cbcd50cc5236a6
+        .quad   0x1f5ec83d3f9846e2
+        .quad   0x8efb23c3328ccb75
+        .quad   0xaf42a207dd876ee9
+        .quad   0x20fbdadc5dfae796
+        .quad   0x241e246b06bf9f51
+
+        // 2^212 * 3 * G
+
+        .quad   0x29e68e57ad6e98f6
+        .quad   0x4c9260c80b462065
+        .quad   0x3f00862ea51ebb4b
+        .quad   0x5bc2c77fb38d9097
+        .quad   0x7eaafc9a6280bbb8
+        .quad   0x22a70f12f403d809
+        .quad   0x31ce40bb1bfc8d20
+        .quad   0x2bc65635e8bd53ee
+        .quad   0xe8d5dc9fa96bad93
+        .quad   0xe58fb17dde1947dc
+        .quad   0x681532ea65185fa3
+        .quad   0x1fdd6c3b034a7830
+
+        // 2^212 * 4 * G
+
+        .quad   0x0a64e28c55dc18fe
+        .quad   0xe3df9e993399ebdd
+        .quad   0x79ac432370e2e652
+        .quad   0x35ff7fc33ae4cc0e
+        .quad   0x9c13a6a52dd8f7a9
+        .quad   0x2dbb1f8c3efdcabf
+        .quad   0x961e32405e08f7b5
+        .quad   0x48c8a121bbe6c9e5
+        .quad   0xfc415a7c59646445
+        .quad   0xd224b2d7c128b615
+        .quad   0x6035c9c905fbb912
+        .quad   0x42d7a91274429fab
+
+        // 2^212 * 5 * G
+
+        .quad   0x4e6213e3eaf72ed3
+        .quad   0x6794981a43acd4e7
+        .quad   0xff547cde6eb508cb
+        .quad   0x6fed19dd10fcb532
+        .quad   0xa9a48947933da5bc
+        .quad   0x4a58920ec2e979ec
+        .quad   0x96d8800013e5ac4c
+        .quad   0x453692d74b48b147
+        .quad   0xdd775d99a8559c6f
+        .quad   0xf42a2140df003e24
+        .quad   0x5223e229da928a66
+        .quad   0x063f46ba6d38f22c
+
+        // 2^212 * 6 * G
+
+        .quad   0xd2d242895f536694
+        .quad   0xca33a2c542939b2c
+        .quad   0x986fada6c7ddb95c
+        .quad   0x5a152c042f712d5d
+        .quad   0x39843cb737346921
+        .quad   0xa747fb0738c89447
+        .quad   0xcb8d8031a245307e
+        .quad   0x67810f8e6d82f068
+        .quad   0x3eeb8fbcd2287db4
+        .quad   0x72c7d3a301a03e93
+        .quad   0x5473e88cbd98265a
+        .quad   0x7324aa515921b403
+
+        // 2^212 * 7 * G
+
+        .quad   0x857942f46c3cbe8e
+        .quad   0xa1d364b14730c046
+        .quad   0x1c8ed914d23c41bf
+        .quad   0x0838e161eef6d5d2
+        .quad   0xad23f6dae82354cb
+        .quad   0x6962502ab6571a6d
+        .quad   0x9b651636e38e37d1
+        .quad   0x5cac5005d1a3312f
+        .quad   0x8cc154cce9e39904
+        .quad   0x5b3a040b84de6846
+        .quad   0xc4d8a61cb1be5d6e
+        .quad   0x40fb897bd8861f02
+
+        // 2^212 * 8 * G
+
+        .quad   0x84c5aa9062de37a1
+        .quad   0x421da5000d1d96e1
+        .quad   0x788286306a9242d9
+        .quad   0x3c5e464a690d10da
+        .quad   0xe57ed8475ab10761
+        .quad   0x71435e206fd13746
+        .quad   0x342f824ecd025632
+        .quad   0x4b16281ea8791e7b
+        .quad   0xd1c101d50b813381
+        .quad   0xdee60f1176ee6828
+        .quad   0x0cb68893383f6409
+        .quad   0x6183c565f6ff484a
+
+        // 2^216 * 1 * G
+
+        .quad   0x741d5a461e6bf9d6
+        .quad   0x2305b3fc7777a581
+        .quad   0xd45574a26474d3d9
+        .quad   0x1926e1dc6401e0ff
+        .quad   0xdb468549af3f666e
+        .quad   0xd77fcf04f14a0ea5
+        .quad   0x3df23ff7a4ba0c47
+        .quad   0x3a10dfe132ce3c85
+        .quad   0xe07f4e8aea17cea0
+        .quad   0x2fd515463a1fc1fd
+        .quad   0x175322fd31f2c0f1
+        .quad   0x1fa1d01d861e5d15
+
+        // 2^216 * 2 * G
+
+        .quad   0xcc8055947d599832
+        .quad   0x1e4656da37f15520
+        .quad   0x99f6f7744e059320
+        .quad   0x773563bc6a75cf33
+        .quad   0x38dcac00d1df94ab
+        .quad   0x2e712bddd1080de9
+        .quad   0x7f13e93efdd5e262
+        .quad   0x73fced18ee9a01e5
+        .quad   0x06b1e90863139cb3
+        .quad   0xa493da67c5a03ecd
+        .quad   0x8d77cec8ad638932
+        .quad   0x1f426b701b864f44
+
+        // 2^216 * 3 * G
+
+        .quad   0xefc9264c41911c01
+        .quad   0xf1a3b7b817a22c25
+        .quad   0x5875da6bf30f1447
+        .quad   0x4e1af5271d31b090
+        .quad   0xf17e35c891a12552
+        .quad   0xb76b8153575e9c76
+        .quad   0xfa83406f0d9b723e
+        .quad   0x0b76bb1b3fa7e438
+        .quad   0x08b8c1f97f92939b
+        .quad   0xbe6771cbd444ab6e
+        .quad   0x22e5646399bb8017
+        .quad   0x7b6dd61eb772a955
+
+        // 2^216 * 4 * G
+
+        .quad   0xb7adc1e850f33d92
+        .quad   0x7998fa4f608cd5cf
+        .quad   0xad962dbd8dfc5bdb
+        .quad   0x703e9bceaf1d2f4f
+        .quad   0x5730abf9ab01d2c7
+        .quad   0x16fb76dc40143b18
+        .quad   0x866cbe65a0cbb281
+        .quad   0x53fa9b659bff6afe
+        .quad   0x6c14c8e994885455
+        .quad   0x843a5d6665aed4e5
+        .quad   0x181bb73ebcd65af1
+        .quad   0x398d93e5c4c61f50
+
+        // 2^216 * 5 * G
+
+        .quad   0x1c4bd16733e248f3
+        .quad   0xbd9e128715bf0a5f
+        .quad   0xd43f8cf0a10b0376
+        .quad   0x53b09b5ddf191b13
+        .quad   0xc3877c60d2e7e3f2
+        .quad   0x3b34aaa030828bb1
+        .quad   0x283e26e7739ef138
+        .quad   0x699c9c9002c30577
+        .quad   0xf306a7235946f1cc
+        .quad   0x921718b5cce5d97d
+        .quad   0x28cdd24781b4e975
+        .quad   0x51caf30c6fcdd907
+
+        // 2^216 * 6 * G
+
+        .quad   0xa60ba7427674e00a
+        .quad   0x630e8570a17a7bf3
+        .quad   0x3758563dcf3324cc
+        .quad   0x5504aa292383fdaa
+        .quad   0x737af99a18ac54c7
+        .quad   0x903378dcc51cb30f
+        .quad   0x2b89bc334ce10cc7
+        .quad   0x12ae29c189f8e99a
+        .quad   0xa99ec0cb1f0d01cf
+        .quad   0x0dd1efcc3a34f7ae
+        .quad   0x55ca7521d09c4e22
+        .quad   0x5fd14fe958eba5ea
+
+        // 2^216 * 7 * G
+
+        .quad   0xb5dc2ddf2845ab2c
+        .quad   0x069491b10a7fe993
+        .quad   0x4daaf3d64002e346
+        .quad   0x093ff26e586474d1
+        .quad   0x3c42fe5ebf93cb8e
+        .quad   0xbedfa85136d4565f
+        .quad   0xe0f0859e884220e8
+        .quad   0x7dd73f960725d128
+        .quad   0xb10d24fe68059829
+        .quad   0x75730672dbaf23e5
+        .quad   0x1367253ab457ac29
+        .quad   0x2f59bcbc86b470a4
+
+        // 2^216 * 8 * G
+
+        .quad   0x83847d429917135f
+        .quad   0xad1b911f567d03d7
+        .quad   0x7e7748d9be77aad1
+        .quad   0x5458b42e2e51af4a
+        .quad   0x7041d560b691c301
+        .quad   0x85201b3fadd7e71e
+        .quad   0x16c2e16311335585
+        .quad   0x2aa55e3d010828b1
+        .quad   0xed5192e60c07444f
+        .quad   0x42c54e2d74421d10
+        .quad   0x352b4c82fdb5c864
+        .quad   0x13e9004a8a768664
+
+        // 2^220 * 1 * G
+
+        .quad   0xcbb5b5556c032bff
+        .quad   0xdf7191b729297a3a
+        .quad   0xc1ff7326aded81bb
+        .quad   0x71ade8bb68be03f5
+        .quad   0x1e6284c5806b467c
+        .quad   0xc5f6997be75d607b
+        .quad   0x8b67d958b378d262
+        .quad   0x3d88d66a81cd8b70
+        .quad   0x8b767a93204ed789
+        .quad   0x762fcacb9fa0ae2a
+        .quad   0x771febcc6dce4887
+        .quad   0x343062158ff05fb3
+
+        // 2^220 * 2 * G
+
+        .quad   0xe05da1a7e1f5bf49
+        .quad   0x26457d6dd4736092
+        .quad   0x77dcb07773cc32f6
+        .quad   0x0a5d94969cdd5fcd
+        .quad   0xfce219072a7b31b4
+        .quad   0x4d7adc75aa578016
+        .quad   0x0ec276a687479324
+        .quad   0x6d6d9d5d1fda4beb
+        .quad   0x22b1a58ae9b08183
+        .quad   0xfd95d071c15c388b
+        .quad   0xa9812376850a0517
+        .quad   0x33384cbabb7f335e
+
+        // 2^220 * 3 * G
+
+        .quad   0x3c6fa2680ca2c7b5
+        .quad   0x1b5082046fb64fda
+        .quad   0xeb53349c5431d6de
+        .quad   0x5278b38f6b879c89
+        .quad   0x33bc627a26218b8d
+        .quad   0xea80b21fc7a80c61
+        .quad   0x9458b12b173e9ee6
+        .quad   0x076247be0e2f3059
+        .quad   0x52e105f61416375a
+        .quad   0xec97af3685abeba4
+        .quad   0x26e6b50623a67c36
+        .quad   0x5cf0e856f3d4fb01
+
+        // 2^220 * 4 * G
+
+        .quad   0xf6c968731ae8cab4
+        .quad   0x5e20741ecb4f92c5
+        .quad   0x2da53be58ccdbc3e
+        .quad   0x2dddfea269970df7
+        .quad   0xbeaece313db342a8
+        .quad   0xcba3635b842db7ee
+        .quad   0xe88c6620817f13ef
+        .quad   0x1b9438aa4e76d5c6
+        .quad   0x8a50777e166f031a
+        .quad   0x067b39f10fb7a328
+        .quad   0x1925c9a6010fbd76
+        .quad   0x6df9b575cc740905
+
+        // 2^220 * 5 * G
+
+        .quad   0x42c1192927f6bdcf
+        .quad   0x8f91917a403d61ca
+        .quad   0xdc1c5a668b9e1f61
+        .quad   0x1596047804ec0f8d
+        .quad   0xecdfc35b48cade41
+        .quad   0x6a88471fb2328270
+        .quad   0x740a4a2440a01b6a
+        .quad   0x471e5796003b5f29
+        .quad   0xda96bbb3aced37ac
+        .quad   0x7a2423b5e9208cea
+        .quad   0x24cc5c3038aebae2
+        .quad   0x50c356afdc5dae2f
+
+        // 2^220 * 6 * G
+
+        .quad   0x09dcbf4341c30318
+        .quad   0xeeba061183181dce
+        .quad   0xc179c0cedc1e29a1
+        .quad   0x1dbf7b89073f35b0
+        .quad   0xcfed9cdf1b31b964
+        .quad   0xf486a9858ca51af3
+        .quad   0x14897265ea8c1f84
+        .quad   0x784a53dd932acc00
+        .quad   0x2d99f9df14fc4920
+        .quad   0x76ccb60cc4499fe5
+        .quad   0xa4132cbbe5cf0003
+        .quad   0x3f93d82354f000ea
+
+        // 2^220 * 7 * G
+
+        .quad   0x8183e7689e04ce85
+        .quad   0x678fb71e04465341
+        .quad   0xad92058f6688edac
+        .quad   0x5da350d3532b099a
+        .quad   0xeaac12d179e14978
+        .quad   0xff923ff3bbebff5e
+        .quad   0x4af663e40663ce27
+        .quad   0x0fd381a811a5f5ff
+        .quad   0xf256aceca436df54
+        .quad   0x108b6168ae69d6e8
+        .quad   0x20d986cb6b5d036c
+        .quad   0x655957b9fee2af50
+
+        // 2^220 * 8 * G
+
+        .quad   0xaea8b07fa902030f
+        .quad   0xf88c766af463d143
+        .quad   0x15b083663c787a60
+        .quad   0x08eab1148267a4a8
+        .quad   0xbdc1409bd002d0ac
+        .quad   0x66660245b5ccd9a6
+        .quad   0x82317dc4fade85ec
+        .quad   0x02fe934b6ad7df0d
+        .quad   0xef5cf100cfb7ea74
+        .quad   0x22897633a1cb42ac
+        .quad   0xd4ce0c54cef285e2
+        .quad   0x30408c048a146a55
+
+        // 2^224 * 1 * G
+
+        .quad   0x739d8845832fcedb
+        .quad   0xfa38d6c9ae6bf863
+        .quad   0x32bc0dcab74ffef7
+        .quad   0x73937e8814bce45e
+        .quad   0xbb2e00c9193b877f
+        .quad   0xece3a890e0dc506b
+        .quad   0xecf3b7c036de649f
+        .quad   0x5f46040898de9e1a
+        .quad   0xb9037116297bf48d
+        .quad   0xa9d13b22d4f06834
+        .quad   0xe19715574696bdc6
+        .quad   0x2cf8a4e891d5e835
+
+        // 2^224 * 2 * G
+
+        .quad   0x6d93fd8707110f67
+        .quad   0xdd4c09d37c38b549
+        .quad   0x7cb16a4cc2736a86
+        .quad   0x2049bd6e58252a09
+        .quad   0x2cb5487e17d06ba2
+        .quad   0x24d2381c3950196b
+        .quad   0xd7659c8185978a30
+        .quad   0x7a6f7f2891d6a4f6
+        .quad   0x7d09fd8d6a9aef49
+        .quad   0xf0ee60be5b3db90b
+        .quad   0x4c21b52c519ebfd4
+        .quad   0x6011aadfc545941d
+
+        // 2^224 * 3 * G
+
+        .quad   0x5f67926dcf95f83c
+        .quad   0x7c7e856171289071
+        .quad   0xd6a1e7f3998f7a5b
+        .quad   0x6fc5cc1b0b62f9e0
+        .quad   0x63ded0c802cbf890
+        .quad   0xfbd098ca0dff6aaa
+        .quad   0x624d0afdb9b6ed99
+        .quad   0x69ce18b779340b1e
+        .quad   0xd1ef5528b29879cb
+        .quad   0xdd1aae3cd47e9092
+        .quad   0x127e0442189f2352
+        .quad   0x15596b3ae57101f1
+
+        // 2^224 * 4 * G
+
+        .quad   0x462739d23f9179a2
+        .quad   0xff83123197d6ddcf
+        .quad   0x1307deb553f2148a
+        .quad   0x0d2237687b5f4dda
+        .quad   0x09ff31167e5124ca
+        .quad   0x0be4158bd9c745df
+        .quad   0x292b7d227ef556e5
+        .quad   0x3aa4e241afb6d138
+        .quad   0x2cc138bf2a3305f5
+        .quad   0x48583f8fa2e926c3
+        .quad   0x083ab1a25549d2eb
+        .quad   0x32fcaa6e4687a36c
+
+        // 2^224 * 5 * G
+
+        .quad   0x7bc56e8dc57d9af5
+        .quad   0x3e0bd2ed9df0bdf2
+        .quad   0xaac014de22efe4a3
+        .quad   0x4627e9cefebd6a5c
+        .quad   0x3207a4732787ccdf
+        .quad   0x17e31908f213e3f8
+        .quad   0xd5b2ecd7f60d964e
+        .quad   0x746f6336c2600be9
+        .quad   0x3f4af345ab6c971c
+        .quad   0xe288eb729943731f
+        .quad   0x33596a8a0344186d
+        .quad   0x7b4917007ed66293
+
+        // 2^224 * 6 * G
+
+        .quad   0x2d85fb5cab84b064
+        .quad   0x497810d289f3bc14
+        .quad   0x476adc447b15ce0c
+        .quad   0x122ba376f844fd7b
+        .quad   0x54341b28dd53a2dd
+        .quad   0xaa17905bdf42fc3f
+        .quad   0x0ff592d94dd2f8f4
+        .quad   0x1d03620fe08cd37d
+        .quad   0xc20232cda2b4e554
+        .quad   0x9ed0fd42115d187f
+        .quad   0x2eabb4be7dd479d9
+        .quad   0x02c70bf52b68ec4c
+
+        // 2^224 * 7 * G
+
+        .quad   0xa287ec4b5d0b2fbb
+        .quad   0x415c5790074882ca
+        .quad   0xe044a61ec1d0815c
+        .quad   0x26334f0a409ef5e0
+        .quad   0xace532bf458d72e1
+        .quad   0x5be768e07cb73cb5
+        .quad   0x56cf7d94ee8bbde7
+        .quad   0x6b0697e3feb43a03
+        .quad   0xb6c8f04adf62a3c0
+        .quad   0x3ef000ef076da45d
+        .quad   0x9c9cb95849f0d2a9
+        .quad   0x1cc37f43441b2fae
+
+        // 2^224 * 8 * G
+
+        .quad   0x508f565a5cc7324f
+        .quad   0xd061c4c0e506a922
+        .quad   0xfb18abdb5c45ac19
+        .quad   0x6c6809c10380314a
+        .quad   0xd76656f1c9ceaeb9
+        .quad   0x1c5b15f818e5656a
+        .quad   0x26e72832844c2334
+        .quad   0x3a346f772f196838
+        .quad   0xd2d55112e2da6ac8
+        .quad   0xe9bd0331b1e851ed
+        .quad   0x960746dd8ec67262
+        .quad   0x05911b9f6ef7c5d0
+
+        // 2^228 * 1 * G
+
+        .quad   0xe9dcd756b637ff2d
+        .quad   0xec4c348fc987f0c4
+        .quad   0xced59285f3fbc7b7
+        .quad   0x3305354793e1ea87
+        .quad   0x01c18980c5fe9f94
+        .quad   0xcd656769716fd5c8
+        .quad   0x816045c3d195a086
+        .quad   0x6e2b7f3266cc7982
+        .quad   0xcc802468f7c3568f
+        .quad   0x9de9ba8219974cb3
+        .quad   0xabb7229cb5b81360
+        .quad   0x44e2017a6fbeba62
+
+        // 2^228 * 2 * G
+
+        .quad   0xc4c2a74354dab774
+        .quad   0x8e5d4c3c4eaf031a
+        .quad   0xb76c23d242838f17
+        .quad   0x749a098f68dce4ea
+        .quad   0x87f82cf3b6ca6ecd
+        .quad   0x580f893e18f4a0c2
+        .quad   0x058930072604e557
+        .quad   0x6cab6ac256d19c1d
+        .quad   0xdcdfe0a02cc1de60
+        .quad   0x032665ff51c5575b
+        .quad   0x2c0c32f1073abeeb
+        .quad   0x6a882014cd7b8606
+
+        // 2^228 * 3 * G
+
+        .quad   0xa52a92fea4747fb5
+        .quad   0xdc12a4491fa5ab89
+        .quad   0xd82da94bb847a4ce
+        .quad   0x4d77edce9512cc4e
+        .quad   0xd111d17caf4feb6e
+        .quad   0x050bba42b33aa4a3
+        .quad   0x17514c3ceeb46c30
+        .quad   0x54bedb8b1bc27d75
+        .quad   0x77c8e14577e2189c
+        .quad   0xa3e46f6aff99c445
+        .quad   0x3144dfc86d335343
+        .quad   0x3a96559e7c4216a9
+
+        // 2^228 * 4 * G
+
+        .quad   0x12550d37f42ad2ee
+        .quad   0x8b78e00498a1fbf5
+        .quad   0x5d53078233894cb2
+        .quad   0x02c84e4e3e498d0c
+        .quad   0x4493896880baaa52
+        .quad   0x4c98afc4f285940e
+        .quad   0xef4aa79ba45448b6
+        .quad   0x5278c510a57aae7f
+        .quad   0xa54dd074294c0b94
+        .quad   0xf55d46b8df18ffb6
+        .quad   0xf06fecc58dae8366
+        .quad   0x588657668190d165
+
+        // 2^228 * 5 * G
+
+        .quad   0xd47712311aef7117
+        .quad   0x50343101229e92c7
+        .quad   0x7a95e1849d159b97
+        .quad   0x2449959b8b5d29c9
+        .quad   0xbf5834f03de25cc3
+        .quad   0xb887c8aed6815496
+        .quad   0x5105221a9481e892
+        .quad   0x6760ed19f7723f93
+        .quad   0x669ba3b7ac35e160
+        .quad   0x2eccf73fba842056
+        .quad   0x1aec1f17c0804f07
+        .quad   0x0d96bc031856f4e7
+
+        // 2^228 * 6 * G
+
+        .quad   0x3318be7775c52d82
+        .quad   0x4cb764b554d0aab9
+        .quad   0xabcf3d27cc773d91
+        .quad   0x3bf4d1848123288a
+        .quad   0xb1d534b0cc7505e1
+        .quad   0x32cd003416c35288
+        .quad   0xcb36a5800762c29d
+        .quad   0x5bfe69b9237a0bf8
+        .quad   0x183eab7e78a151ab
+        .quad   0xbbe990c999093763
+        .quad   0xff717d6e4ac7e335
+        .quad   0x4c5cddb325f39f88
+
+        // 2^228 * 7 * G
+
+        .quad   0xc0f6b74d6190a6eb
+        .quad   0x20ea81a42db8f4e4
+        .quad   0xa8bd6f7d97315760
+        .quad   0x33b1d60262ac7c21
+        .quad   0x57750967e7a9f902
+        .quad   0x2c37fdfc4f5b467e
+        .quad   0xb261663a3177ba46
+        .quad   0x3a375e78dc2d532b
+        .quad   0x8141e72f2d4dddea
+        .quad   0xe6eafe9862c607c8
+        .quad   0x23c28458573cafd0
+        .quad   0x46b9476f4ff97346
+
+        // 2^228 * 8 * G
+
+        .quad   0x0c1ffea44f901e5c
+        .quad   0x2b0b6fb72184b782
+        .quad   0xe587ff910114db88
+        .quad   0x37130f364785a142
+        .quad   0x1215505c0d58359f
+        .quad   0x2a2013c7fc28c46b
+        .quad   0x24a0a1af89ea664e
+        .quad   0x4400b638a1130e1f
+        .quad   0x3a01b76496ed19c3
+        .quad   0x31e00ab0ed327230
+        .quad   0x520a885783ca15b1
+        .quad   0x06aab9875accbec7
+
+        // 2^232 * 1 * G
+
+        .quad   0xc1339983f5df0ebb
+        .quad   0xc0f3758f512c4cac
+        .quad   0x2cf1130a0bb398e1
+        .quad   0x6b3cecf9aa270c62
+        .quad   0x5349acf3512eeaef
+        .quad   0x20c141d31cc1cb49
+        .quad   0x24180c07a99a688d
+        .quad   0x555ef9d1c64b2d17
+        .quad   0x36a770ba3b73bd08
+        .quad   0x624aef08a3afbf0c
+        .quad   0x5737ff98b40946f2
+        .quad   0x675f4de13381749d
+
+        // 2^232 * 2 * G
+
+        .quad   0x0e2c52036b1782fc
+        .quad   0x64816c816cad83b4
+        .quad   0xd0dcbdd96964073e
+        .quad   0x13d99df70164c520
+        .quad   0xa12ff6d93bdab31d
+        .quad   0x0725d80f9d652dfe
+        .quad   0x019c4ff39abe9487
+        .quad   0x60f450b882cd3c43
+        .quad   0x014b5ec321e5c0ca
+        .quad   0x4fcb69c9d719bfa2
+        .quad   0x4e5f1c18750023a0
+        .quad   0x1c06de9e55edac80
+
+        // 2^232 * 3 * G
+
+        .quad   0x990f7ad6a33ec4e2
+        .quad   0x6608f938be2ee08e
+        .quad   0x9ca143c563284515
+        .quad   0x4cf38a1fec2db60d
+        .quad   0xffd52b40ff6d69aa
+        .quad   0x34530b18dc4049bb
+        .quad   0x5e4a5c2fa34d9897
+        .quad   0x78096f8e7d32ba2d
+        .quad   0xa0aaaa650dfa5ce7
+        .quad   0xf9c49e2a48b5478c
+        .quad   0x4f09cc7d7003725b
+        .quad   0x373cad3a26091abe
+
+        // 2^232 * 4 * G
+
+        .quad   0xb294634d82c9f57c
+        .quad   0x1fcbfde124934536
+        .quad   0x9e9c4db3418cdb5a
+        .quad   0x0040f3d9454419fc
+        .quad   0xf1bea8fb89ddbbad
+        .quad   0x3bcb2cbc61aeaecb
+        .quad   0x8f58a7bb1f9b8d9d
+        .quad   0x21547eda5112a686
+        .quad   0xdefde939fd5986d3
+        .quad   0xf4272c89510a380c
+        .quad   0xb72ba407bb3119b9
+        .quad   0x63550a334a254df4
+
+        // 2^232 * 5 * G
+
+        .quad   0x6507d6edb569cf37
+        .quad   0x178429b00ca52ee1
+        .quad   0xea7c0090eb6bd65d
+        .quad   0x3eea62c7daf78f51
+        .quad   0x9bba584572547b49
+        .quad   0xf305c6fae2c408e0
+        .quad   0x60e8fa69c734f18d
+        .quad   0x39a92bafaa7d767a
+        .quad   0x9d24c713e693274e
+        .quad   0x5f63857768dbd375
+        .quad   0x70525560eb8ab39a
+        .quad   0x68436a0665c9c4cd
+
+        // 2^232 * 6 * G
+
+        .quad   0xbc0235e8202f3f27
+        .quad   0xc75c00e264f975b0
+        .quad   0x91a4e9d5a38c2416
+        .quad   0x17b6e7f68ab789f9
+        .quad   0x1e56d317e820107c
+        .quad   0xc5266844840ae965
+        .quad   0xc1e0a1c6320ffc7a
+        .quad   0x5373669c91611472
+        .quad   0x5d2814ab9a0e5257
+        .quad   0x908f2084c9cab3fc
+        .quad   0xafcaf5885b2d1eca
+        .quad   0x1cb4b5a678f87d11
+
+        // 2^232 * 7 * G
+
+        .quad   0xb664c06b394afc6c
+        .quad   0x0c88de2498da5fb1
+        .quad   0x4f8d03164bcad834
+        .quad   0x330bca78de7434a2
+        .quad   0x6b74aa62a2a007e7
+        .quad   0xf311e0b0f071c7b1
+        .quad   0x5707e438000be223
+        .quad   0x2dc0fd2d82ef6eac
+        .quad   0x982eff841119744e
+        .quad   0xf9695e962b074724
+        .quad   0xc58ac14fbfc953fb
+        .quad   0x3c31be1b369f1cf5
+
+        // 2^232 * 8 * G
+
+        .quad   0xb0f4864d08948aee
+        .quad   0x07dc19ee91ba1c6f
+        .quad   0x7975cdaea6aca158
+        .quad   0x330b61134262d4bb
+        .quad   0xc168bc93f9cb4272
+        .quad   0xaeb8711fc7cedb98
+        .quad   0x7f0e52aa34ac8d7a
+        .quad   0x41cec1097e7d55bb
+        .quad   0xf79619d7a26d808a
+        .quad   0xbb1fd49e1d9e156d
+        .quad   0x73d7c36cdba1df27
+        .quad   0x26b44cd91f28777d
+
+        // 2^236 * 1 * G
+
+        .quad   0x300a9035393aa6d8
+        .quad   0x2b501131a12bb1cd
+        .quad   0x7b1ff677f093c222
+        .quad   0x4309c1f8cab82bad
+        .quad   0xaf44842db0285f37
+        .quad   0x8753189047efc8df
+        .quad   0x9574e091f820979a
+        .quad   0x0e378d6069615579
+        .quad   0xd9fa917183075a55
+        .quad   0x4bdb5ad26b009fdc
+        .quad   0x7829ad2cd63def0e
+        .quad   0x078fc54975fd3877
+
+        // 2^236 * 2 * G
+
+        .quad   0x87dfbd1428878f2d
+        .quad   0x134636dd1e9421a1
+        .quad   0x4f17c951257341a3
+        .quad   0x5df98d4bad296cb8
+        .quad   0xe2004b5bb833a98a
+        .quad   0x44775dec2d4c3330
+        .quad   0x3aa244067eace913
+        .quad   0x272630e3d58e00a9
+        .quad   0xf3678fd0ecc90b54
+        .quad   0xf001459b12043599
+        .quad   0x26725fbc3758b89b
+        .quad   0x4325e4aa73a719ae
+
+        // 2^236 * 3 * G
+
+        .quad   0x657dc6ef433c3493
+        .quad   0x65375e9f80dbf8c3
+        .quad   0x47fd2d465b372dae
+        .quad   0x4966ab79796e7947
+        .quad   0xed24629acf69f59d
+        .quad   0x2a4a1ccedd5abbf4
+        .quad   0x3535ca1f56b2d67b
+        .quad   0x5d8c68d043b1b42d
+        .quad   0xee332d4de3b42b0a
+        .quad   0xd84e5a2b16a4601c
+        .quad   0x78243877078ba3e4
+        .quad   0x77ed1eb4184ee437
+
+        // 2^236 * 4 * G
+
+        .quad   0xbfd4e13f201839a0
+        .quad   0xaeefffe23e3df161
+        .quad   0xb65b04f06b5d1fe3
+        .quad   0x52e085fb2b62fbc0
+        .quad   0x185d43f89e92ed1a
+        .quad   0xb04a1eeafe4719c6
+        .quad   0x499fbe88a6f03f4f
+        .quad   0x5d8b0d2f3c859bdd
+        .quad   0x124079eaa54cf2ba
+        .quad   0xd72465eb001b26e7
+        .quad   0x6843bcfdc97af7fd
+        .quad   0x0524b42b55eacd02
+
+        // 2^236 * 5 * G
+
+        .quad   0xfd0d5dbee45447b0
+        .quad   0x6cec351a092005ee
+        .quad   0x99a47844567579cb
+        .quad   0x59d242a216e7fa45
+        .quad   0xbc18dcad9b829eac
+        .quad   0x23ae7d28b5f579d0
+        .quad   0xc346122a69384233
+        .quad   0x1a6110b2e7d4ac89
+        .quad   0x4f833f6ae66997ac
+        .quad   0x6849762a361839a4
+        .quad   0x6985dec1970ab525
+        .quad   0x53045e89dcb1f546
+
+        // 2^236 * 6 * G
+
+        .quad   0xcb8bb346d75353db
+        .quad   0xfcfcb24bae511e22
+        .quad   0xcba48d40d50ae6ef
+        .quad   0x26e3bae5f4f7cb5d
+        .quad   0x84da3cde8d45fe12
+        .quad   0xbd42c218e444e2d2
+        .quad   0xa85196781f7e3598
+        .quad   0x7642c93f5616e2b2
+        .quad   0x2323daa74595f8e4
+        .quad   0xde688c8b857abeb4
+        .quad   0x3fc48e961c59326e
+        .quad   0x0b2e73ca15c9b8ba
+
+        // 2^236 * 7 * G
+
+        .quad   0xd6bb4428c17f5026
+        .quad   0x9eb27223fb5a9ca7
+        .quad   0xe37ba5031919c644
+        .quad   0x21ce380db59a6602
+        .quad   0x0e3fbfaf79c03a55
+        .quad   0x3077af054cbb5acf
+        .quad   0xd5c55245db3de39f
+        .quad   0x015e68c1476a4af7
+        .quad   0xc1d5285220066a38
+        .quad   0x95603e523570aef3
+        .quad   0x832659a7226b8a4d
+        .quad   0x5dd689091f8eedc9
+
+        // 2^236 * 8 * G
+
+        .quad   0xcbac84debfd3c856
+        .quad   0x1624c348b35ff244
+        .quad   0xb7f88dca5d9cad07
+        .quad   0x3b0e574da2c2ebe8
+        .quad   0x1d022591a5313084
+        .quad   0xca2d4aaed6270872
+        .quad   0x86a12b852f0bfd20
+        .quad   0x56e6c439ad7da748
+        .quad   0xc704ff4942bdbae6
+        .quad   0x5e21ade2b2de1f79
+        .quad   0xe95db3f35652fad8
+        .quad   0x0822b5378f08ebc1
+
+        // 2^240 * 1 * G
+
+        .quad   0x51f048478f387475
+        .quad   0xb25dbcf49cbecb3c
+        .quad   0x9aab1244d99f2055
+        .quad   0x2c709e6c1c10a5d6
+        .quad   0xe1b7f29362730383
+        .quad   0x4b5279ffebca8a2c
+        .quad   0xdafc778abfd41314
+        .quad   0x7deb10149c72610f
+        .quad   0xcb62af6a8766ee7a
+        .quad   0x66cbec045553cd0e
+        .quad   0x588001380f0be4b5
+        .quad   0x08e68e9ff62ce2ea
+
+        // 2^240 * 2 * G
+
+        .quad   0x34ad500a4bc130ad
+        .quad   0x8d38db493d0bd49c
+        .quad   0xa25c3d98500a89be
+        .quad   0x2f1f3f87eeba3b09
+        .quad   0x2f2d09d50ab8f2f9
+        .quad   0xacb9218dc55923df
+        .quad   0x4a8f342673766cb9
+        .quad   0x4cb13bd738f719f5
+        .quad   0xf7848c75e515b64a
+        .quad   0xa59501badb4a9038
+        .quad   0xc20d313f3f751b50
+        .quad   0x19a1e353c0ae2ee8
+
+        // 2^240 * 3 * G
+
+        .quad   0x7d1c7560bafa05c3
+        .quad   0xb3e1a0a0c6e55e61
+        .quad   0xe3529718c0d66473
+        .quad   0x41546b11c20c3486
+        .quad   0xb42172cdd596bdbd
+        .quad   0x93e0454398eefc40
+        .quad   0x9fb15347b44109b5
+        .quad   0x736bd3990266ae34
+        .quad   0x85532d509334b3b4
+        .quad   0x46fd114b60816573
+        .quad   0xcc5f5f30425c8375
+        .quad   0x412295a2b87fab5c
+
+        // 2^240 * 4 * G
+
+        .quad   0x19c99b88f57ed6e9
+        .quad   0x5393cb266df8c825
+        .quad   0x5cee3213b30ad273
+        .quad   0x14e153ebb52d2e34
+        .quad   0x2e655261e293eac6
+        .quad   0x845a92032133acdb
+        .quad   0x460975cb7900996b
+        .quad   0x0760bb8d195add80
+        .quad   0x413e1a17cde6818a
+        .quad   0x57156da9ed69a084
+        .quad   0x2cbf268f46caccb1
+        .quad   0x6b34be9bc33ac5f2
+
+        // 2^240 * 5 * G
+
+        .quad   0xf3df2f643a78c0b2
+        .quad   0x4c3e971ef22e027c
+        .quad   0xec7d1c5e49c1b5a3
+        .quad   0x2012c18f0922dd2d
+        .quad   0x11fc69656571f2d3
+        .quad   0xc6c9e845530e737a
+        .quad   0xe33ae7a2d4fe5035
+        .quad   0x01b9c7b62e6dd30b
+        .quad   0x880b55e55ac89d29
+        .quad   0x1483241f45a0a763
+        .quad   0x3d36efdfc2e76c1f
+        .quad   0x08af5b784e4bade8
+
+        // 2^240 * 6 * G
+
+        .quad   0x283499dc881f2533
+        .quad   0x9d0525da779323b6
+        .quad   0x897addfb673441f4
+        .quad   0x32b79d71163a168d
+        .quad   0xe27314d289cc2c4b
+        .quad   0x4be4bd11a287178d
+        .quad   0x18d528d6fa3364ce
+        .quad   0x6423c1d5afd9826e
+        .quad   0xcc85f8d9edfcb36a
+        .quad   0x22bcc28f3746e5f9
+        .quad   0xe49de338f9e5d3cd
+        .quad   0x480a5efbc13e2dcc
+
+        // 2^240 * 7 * G
+
+        .quad   0x0b51e70b01622071
+        .quad   0x06b505cf8b1dafc5
+        .quad   0x2c6bb061ef5aabcd
+        .quad   0x47aa27600cb7bf31
+        .quad   0xb6614ce442ce221f
+        .quad   0x6e199dcc4c053928
+        .quad   0x663fb4a4dc1cbe03
+        .quad   0x24b31d47691c8e06
+        .quad   0x2a541eedc015f8c3
+        .quad   0x11a4fe7e7c693f7c
+        .quad   0xf0af66134ea278d6
+        .quad   0x545b585d14dda094
+
+        // 2^240 * 8 * G
+
+        .quad   0x67bf275ea0d43a0f
+        .quad   0xade68e34089beebe
+        .quad   0x4289134cd479e72e
+        .quad   0x0f62f9c332ba5454
+        .quad   0x6204e4d0e3b321e1
+        .quad   0x3baa637a28ff1e95
+        .quad   0x0b0ccffd5b99bd9e
+        .quad   0x4d22dc3e64c8d071
+        .quad   0xfcb46589d63b5f39
+        .quad   0x5cae6a3f57cbcf61
+        .quad   0xfebac2d2953afa05
+        .quad   0x1c0fa01a36371436
+
+        // 2^244 * 1 * G
+
+        .quad   0xe7547449bc7cd692
+        .quad   0x0f9abeaae6f73ddf
+        .quad   0x4af01ca700837e29
+        .quad   0x63ab1b5d3f1bc183
+        .quad   0xc11ee5e854c53fae
+        .quad   0x6a0b06c12b4f3ff4
+        .quad   0x33540f80e0b67a72
+        .quad   0x15f18fc3cd07e3ef
+        .quad   0x32750763b028f48c
+        .quad   0x06020740556a065f
+        .quad   0xd53bd812c3495b58
+        .quad   0x08706c9b865f508d
+
+        // 2^244 * 2 * G
+
+        .quad   0xf37ca2ab3d343dff
+        .quad   0x1a8c6a2d80abc617
+        .quad   0x8e49e035d4ccffca
+        .quad   0x48b46beebaa1d1b9
+        .quad   0xcc991b4138b41246
+        .quad   0x243b9c526f9ac26b
+        .quad   0xb9ef494db7cbabbd
+        .quad   0x5fba433dd082ed00
+        .quad   0x9c49e355c9941ad0
+        .quad   0xb9734ade74498f84
+        .quad   0x41c3fed066663e5c
+        .quad   0x0ecfedf8e8e710b3
+
+        // 2^244 * 3 * G
+
+        .quad   0x76430f9f9cd470d9
+        .quad   0xb62acc9ba42f6008
+        .quad   0x1898297c59adad5e
+        .quad   0x7789dd2db78c5080
+        .quad   0x744f7463e9403762
+        .quad   0xf79a8dee8dfcc9c9
+        .quad   0x163a649655e4cde3
+        .quad   0x3b61788db284f435
+        .quad   0xb22228190d6ef6b2
+        .quad   0xa94a66b246ce4bfa
+        .quad   0x46c1a77a4f0b6cc7
+        .quad   0x4236ccffeb7338cf
+
+        // 2^244 * 4 * G
+
+        .quad   0x8497404d0d55e274
+        .quad   0x6c6663d9c4ad2b53
+        .quad   0xec2fb0d9ada95734
+        .quad   0x2617e120cdb8f73c
+        .quad   0x3bd82dbfda777df6
+        .quad   0x71b177cc0b98369e
+        .quad   0x1d0e8463850c3699
+        .quad   0x5a71945b48e2d1f1
+        .quad   0x6f203dd5405b4b42
+        .quad   0x327ec60410b24509
+        .quad   0x9c347230ac2a8846
+        .quad   0x77de29fc11ffeb6a
+
+        // 2^244 * 5 * G
+
+        .quad   0xb0ac57c983b778a8
+        .quad   0x53cdcca9d7fe912c
+        .quad   0x61c2b854ff1f59dc
+        .quad   0x3a1a2cf0f0de7dac
+        .quad   0x835e138fecced2ca
+        .quad   0x8c9eaf13ea963b9a
+        .quad   0xc95fbfc0b2160ea6
+        .quad   0x575e66f3ad877892
+        .quad   0x99803a27c88fcb3a
+        .quad   0x345a6789275ec0b0
+        .quad   0x459789d0ff6c2be5
+        .quad   0x62f882651e70a8b2
+
+        // 2^244 * 6 * G
+
+        .quad   0x085ae2c759ff1be4
+        .quad   0x149145c93b0e40b7
+        .quad   0xc467e7fa7ff27379
+        .quad   0x4eeecf0ad5c73a95
+        .quad   0x6d822986698a19e0
+        .quad   0xdc9821e174d78a71
+        .quad   0x41a85f31f6cb1f47
+        .quad   0x352721c2bcda9c51
+        .quad   0x48329952213fc985
+        .quad   0x1087cf0d368a1746
+        .quad   0x8e5261b166c15aa5
+        .quad   0x2d5b2d842ed24c21
+
+        // 2^244 * 7 * G
+
+        .quad   0x02cfebd9ebd3ded1
+        .quad   0xd45b217739021974
+        .quad   0x7576f813fe30a1b7
+        .quad   0x5691b6f9a34ef6c2
+        .quad   0x5eb7d13d196ac533
+        .quad   0x377234ecdb80be2b
+        .quad   0xe144cffc7cf5ae24
+        .quad   0x5226bcf9c441acec
+        .quad   0x79ee6c7223e5b547
+        .quad   0x6f5f50768330d679
+        .quad   0xed73e1e96d8adce9
+        .quad   0x27c3da1e1d8ccc03
+
+        // 2^244 * 8 * G
+
+        .quad   0x7eb9efb23fe24c74
+        .quad   0x3e50f49f1651be01
+        .quad   0x3ea732dc21858dea
+        .quad   0x17377bd75bb810f9
+        .quad   0x28302e71630ef9f6
+        .quad   0xc2d4a2032b64cee0
+        .quad   0x090820304b6292be
+        .quad   0x5fca747aa82adf18
+        .quad   0x232a03c35c258ea5
+        .quad   0x86f23a2c6bcb0cf1
+        .quad   0x3dad8d0d2e442166
+        .quad   0x04a8933cab76862b
+
+        // 2^248 * 1 * G
+
+        .quad   0xd2c604b622943dff
+        .quad   0xbc8cbece44cfb3a0
+        .quad   0x5d254ff397808678
+        .quad   0x0fa3614f3b1ca6bf
+        .quad   0x69082b0e8c936a50
+        .quad   0xf9c9a035c1dac5b6
+        .quad   0x6fb73e54c4dfb634
+        .quad   0x4005419b1d2bc140
+        .quad   0xa003febdb9be82f0
+        .quad   0x2089c1af3a44ac90
+        .quad   0xf8499f911954fa8e
+        .quad   0x1fba218aef40ab42
+
+        // 2^248 * 2 * G
+
+        .quad   0xab549448fac8f53e
+        .quad   0x81f6e89a7ba63741
+        .quad   0x74fd6c7d6c2b5e01
+        .quad   0x392e3acaa8c86e42
+        .quad   0x4f3e57043e7b0194
+        .quad   0xa81d3eee08daaf7f
+        .quad   0xc839c6ab99dcdef1
+        .quad   0x6c535d13ff7761d5
+        .quad   0x4cbd34e93e8a35af
+        .quad   0x2e0781445887e816
+        .quad   0x19319c76f29ab0ab
+        .quad   0x25e17fe4d50ac13b
+
+        // 2^248 * 3 * G
+
+        .quad   0x0a289bd71e04f676
+        .quad   0x208e1c52d6420f95
+        .quad   0x5186d8b034691fab
+        .quad   0x255751442a9fb351
+        .quad   0x915f7ff576f121a7
+        .quad   0xc34a32272fcd87e3
+        .quad   0xccba2fde4d1be526
+        .quad   0x6bba828f8969899b
+        .quad   0xe2d1bc6690fe3901
+        .quad   0x4cb54a18a0997ad5
+        .quad   0x971d6914af8460d4
+        .quad   0x559d504f7f6b7be4
+
+        // 2^248 * 4 * G
+
+        .quad   0xa7738378b3eb54d5
+        .quad   0x1d69d366a5553c7c
+        .quad   0x0a26cf62f92800ba
+        .quad   0x01ab12d5807e3217
+        .quad   0x9c4891e7f6d266fd
+        .quad   0x0744a19b0307781b
+        .quad   0x88388f1d6061e23b
+        .quad   0x123ea6a3354bd50e
+        .quad   0x118d189041e32d96
+        .quad   0xb9ede3c2d8315848
+        .quad   0x1eab4271d83245d9
+        .quad   0x4a3961e2c918a154
+
+        // 2^248 * 5 * G
+
+        .quad   0x71dc3be0f8e6bba0
+        .quad   0xd6cef8347effe30a
+        .quad   0xa992425fe13a476a
+        .quad   0x2cd6bce3fb1db763
+        .quad   0x0327d644f3233f1e
+        .quad   0x499a260e34fcf016
+        .quad   0x83b5a716f2dab979
+        .quad   0x68aceead9bd4111f
+        .quad   0x38b4c90ef3d7c210
+        .quad   0x308e6e24b7ad040c
+        .quad   0x3860d9f1b7e73e23
+        .quad   0x595760d5b508f597
+
+        // 2^248 * 6 * G
+
+        .quad   0x6129bfe104aa6397
+        .quad   0x8f960008a4a7fccb
+        .quad   0x3f8bc0897d909458
+        .quad   0x709fa43edcb291a9
+        .quad   0x882acbebfd022790
+        .quad   0x89af3305c4115760
+        .quad   0x65f492e37d3473f4
+        .quad   0x2cb2c5df54515a2b
+        .quad   0xeb0a5d8c63fd2aca
+        .quad   0xd22bc1662e694eff
+        .quad   0x2723f36ef8cbb03a
+        .quad   0x70f029ecf0c8131f
+
+        // 2^248 * 7 * G
+
+        .quad   0x461307b32eed3e33
+        .quad   0xae042f33a45581e7
+        .quad   0xc94449d3195f0366
+        .quad   0x0b7d5d8a6c314858
+        .quad   0x2a6aafaa5e10b0b9
+        .quad   0x78f0a370ef041aa9
+        .quad   0x773efb77aa3ad61f
+        .quad   0x44eca5a2a74bd9e1
+        .quad   0x25d448327b95d543
+        .quad   0x70d38300a3340f1d
+        .quad   0xde1c531c60e1c52b
+        .quad   0x272224512c7de9e4
+
+        // 2^248 * 8 * G
+
+        .quad   0x1abc92af49c5342e
+        .quad   0xffeed811b2e6fad0
+        .quad   0xefa28c8dfcc84e29
+        .quad   0x11b5df18a44cc543
+        .quad   0xbf7bbb8a42a975fc
+        .quad   0x8c5c397796ada358
+        .quad   0xe27fc76fcdedaa48
+        .quad   0x19735fd7f6bc20a6
+        .quad   0xe3ab90d042c84266
+        .quad   0xeb848e0f7f19547e
+        .quad   0x2503a1d065a497b9
+        .quad   0x0fef911191df895f
diff --git a/cbits/s2n/x86_att/p256_montjadd.S b/cbits/s2n/x86_att/p256_montjadd.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjadd.S
@@ -0,0 +1,593 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjadd(uint64_t p3[static 12], const uint64_t p1[static 12],
+//                              const uint64_t p2[static 12]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1, RDX = p2
+// Microsoft x64 ABI:   RCX = p3, RDX = p1, R8 = p2
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjadd)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjadd)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjadd)
+        .text
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs
+// These assume %rdi = p3, %rsi = p1 and %rbp = p2,
+// which needs to be set up explicitly before use.
+// The first two hold initially, and the second is
+// set up by copying the initial %rdx input to %rbp.
+// Thereafter, no code macro modifies any of them.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_2 0(%rbp)
+#define y_2 NUMSIZE(%rbp)
+#define z_2 (2*NUMSIZE)(%rbp)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// NSPACE is the total stack needed for these temporaries
+
+#define z1sq (NUMSIZE*0)(%rsp)
+#define ww (NUMSIZE*0)(%rsp)
+#define resx (NUMSIZE*0)(%rsp)
+
+#define yd (NUMSIZE*1)(%rsp)
+#define y2a (NUMSIZE*1)(%rsp)
+
+#define x2a (NUMSIZE*2)(%rsp)
+#define zzx2 (NUMSIZE*2)(%rsp)
+
+#define zz (NUMSIZE*3)(%rsp)
+#define t1 (NUMSIZE*3)(%rsp)
+
+#define t2 (NUMSIZE*4)(%rsp)
+#define x1a (NUMSIZE*4)(%rsp)
+#define zzx1 (NUMSIZE*4)(%rsp)
+#define resy (NUMSIZE*4)(%rsp)
+
+#define xd (NUMSIZE*5)(%rsp)
+#define z2sq (NUMSIZE*5)(%rsp)
+#define resz (NUMSIZE*5)(%rsp)
+
+#define y1a (NUMSIZE*6)(%rsp)
+
+#define NSPACE NUMSIZE*7
+
+// Corresponds exactly to bignum_montmul_p256
+
+#define montmul_p256(P0,P1,P2)                  \
+        xorl    %r13d, %r13d ;                      \
+        movq    P2, %rdx ;                       \
+        mulxq   P1, %r8, %r9 ;                     \
+        mulxq   0x8+P1, %rbx, %r10 ;               \
+        adcq    %rbx, %r9 ;                         \
+        mulxq   0x10+P1, %rbx, %r11 ;              \
+        adcq    %rbx, %r10 ;                        \
+        mulxq   0x18+P1, %rbx, %r12 ;              \
+        adcq    %rbx, %r11 ;                        \
+        adcq    %r13, %r12 ;                        \
+        movq    0x8+P2, %rdx ;                   \
+        xorl    %r14d, %r14d ;                      \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcq    %r14, %r13 ;                        \
+        xorl    %r15d, %r15d ;                      \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %r15, %r13 ;                        \
+        adoxq   %r15, %r14 ;                        \
+        adcq    %r15, %r14 ;                        \
+        movq    0x10+P2, %rdx ;                  \
+        xorl    %r8d, %r8d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adoxq   %r8, %r14 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r13 ;                        \
+        adcq    %rbx, %r14 ;                        \
+        adcq    %r8, %r15 ;                         \
+        movq    0x18+P2, %rdx ;                  \
+        xorl    %r9d, %r9d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        adoxq   %r9, %r15 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r14 ;                        \
+        adcq    %rbx, %r15 ;                        \
+        adcq    %r9, %r8 ;                          \
+        xorl    %r9d, %r9d ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %r9, %r15 ;                         \
+        adoxq   %r9, %r8 ;                          \
+        adcq    %r9, %r8 ;                          \
+        movl    $0x1, %ecx ;                        \
+        addq    %r12, %rcx ;                        \
+        decq    %rdx;                            \
+        adcq    %r13, %rdx ;                        \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                         \
+        adcq    %r14, %r9 ;                         \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rcx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %r9, %r14 ;                         \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256 except for
+// register tweaks to avoid modifying %rbp.
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rdx ;                       \
+        mulxq   %rdx, %r8, %r15 ;                     \
+        mulxq   0x8+P1, %r9, %r10 ;                \
+        mulxq   0x18+P1, %r11, %r12 ;              \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   0x18+P1, %r13, %r14 ;              \
+        xorl    %ecx, %ecx ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        adoxq   %rcx, %r14 ;                        \
+        adcq    %rcx, %r14 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        adcxq   %r9, %r9 ;                          \
+        adoxq   %r15, %r9 ;                         \
+        movq    0x8+P1, %rdx ;                   \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r10, %r10 ;                        \
+        adoxq   %rax, %r10 ;                        \
+        adcxq   %r11, %r11 ;                        \
+        adoxq   %rdx, %r11 ;                        \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r12, %r12 ;                        \
+        adoxq   %rax, %r12 ;                        \
+        adcxq   %r13, %r13 ;                        \
+        adoxq   %rdx, %r13 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %r15 ;                    \
+        adcxq   %r14, %r14 ;                        \
+        adoxq   %rax, %r14 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r15 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        movl    %ecx, %r9d ;                        \
+        adoxq   %rcx, %r9 ;                         \
+        adcxq   %rcx, %r9 ;                         \
+        addq    %r9, %r14 ;                         \
+        adcq    %rcx, %r15 ;                        \
+        movl    %ecx, %r8d ;                        \
+        adcq    %rcx, %r8 ;                         \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r8 ;                         \
+        adcq    %rcx, %r8 ;                         \
+        movl    $0x1, %ebx ;                        \
+        addq    %r12, %rbx ;                        \
+        leaq    -0x1(%rdx), %rdx ;                  \
+        adcq    %r13, %rdx ;                        \
+        leaq    -0x1(%rcx), %rcx ;                  \
+        movq    %rcx, %rax ;                        \
+        adcq    %r14, %rcx ;                        \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rbx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %rcx, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Almost-Montgomery variant which we use when an input to other muls
+// with the other argument fully reduced (which is always safe).
+// Again, the basic squaring code is tweaked to avoid modifying %rbp.
+
+#define amontsqr_p256(P0,P1)                    \
+        movq    P1, %rdx ;                       \
+        mulxq   %rdx, %r8, %r15 ;                     \
+        mulxq   0x8+P1, %r9, %r10 ;                \
+        mulxq   0x18+P1, %r11, %r12 ;              \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   0x18+P1, %r13, %r14 ;              \
+        xorl    %ecx, %ecx ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        adoxq   %rcx, %r14 ;                        \
+        adcq    %rcx, %r14 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        adcxq   %r9, %r9 ;                          \
+        adoxq   %r15, %r9 ;                         \
+        movq    0x8+P1, %rdx ;                   \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r10, %r10 ;                        \
+        adoxq   %rax, %r10 ;                        \
+        adcxq   %r11, %r11 ;                        \
+        adoxq   %rdx, %r11 ;                        \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r12, %r12 ;                        \
+        adoxq   %rax, %r12 ;                        \
+        adcxq   %r13, %r13 ;                        \
+        adoxq   %rdx, %r13 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %r15 ;                    \
+        adcxq   %r14, %r14 ;                        \
+        adoxq   %rax, %r14 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r15 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        movl    %ecx, %r9d ;                        \
+        adoxq   %rcx, %r9 ;                         \
+        adcxq   %rcx, %r9 ;                         \
+        addq    %r9, %r14 ;                         \
+        adcq    %rcx, %r15 ;                        \
+        movl    %ecx, %r8d ;                        \
+        adcq    %rcx, %r8 ;                         \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r8 ;                         \
+        adcq    %rcx, %r8 ;                         \
+        movl    $0x1, %r8d ;                        \
+        leaq    -0x1(%rdx), %rdx ;                  \
+        leaq    -0x1(%rcx), %rax ;                  \
+        movl    $0xfffffffe, %r11d ;                \
+        cmovzq  %rcx, %r8 ;                         \
+        cmovzq  %rcx, %rdx ;                        \
+        cmovzq  %rcx, %rax ;                        \
+        cmovzq  %rcx, %r11 ;                        \
+        addq    %r8, %r12 ;                         \
+        adcq    %rdx, %r13 ;                        \
+        adcq    %rax, %r14 ;                        \
+        adcq    %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Additional macros to help with final multiplexing
+
+#define load4(r0,r1,r2,r3,P)                    \
+        movq    P, r0 ;                        \
+        movq    8+P, r1 ;                      \
+        movq    16+P, r2 ;                     \
+        movq    24+P, r3
+
+#define store4(P,r0,r1,r2,r3)                   \
+        movq    r0, P ;                        \
+        movq    r1, 8+P ;                      \
+        movq    r2, 16+P ;                     \
+        movq    r3, 24+P
+
+#define czload4(r0,r1,r2,r3,P)                  \
+        cmovzq  P, r0 ;                        \
+        cmovzq  8+P, r1 ;                      \
+        cmovzq  16+P, r2 ;                     \
+        cmovzq  24+P, r3
+
+#define muxload4(r0,r1,r2,r3,P0,P1,P2)          \
+        movq    P0, r0 ;                       \
+        cmovbq  P1, r0 ;                       \
+        cmovnbe P2, r0 ;                       \
+        movq    8+P0, r1 ;                     \
+        cmovbq  8+P1, r1 ;                     \
+        cmovnbe 8+P2, r1 ;                     \
+        movq    16+P0, r2 ;                    \
+        cmovbq  16+P1, r2 ;                    \
+        cmovnbe 16+P2, r2 ;                    \
+        movq    24+P0, r3 ;                    \
+        cmovbq  24+P1, r3 ;                    \
+        cmovnbe 24+P2, r3
+
+S2N_BN_SYMBOL(p256_montjadd):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        movq    %r8, %rdx
+#endif
+
+// Save registers and make room on stack for temporary variables
+// Put the input y in %rbp where it lasts as long as it's needed.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+        movq    %rdx, %rbp
+
+// Main code, just a sequence of basic field operations
+// 12 * multiply + 4 * square + 7 * subtract
+
+        amontsqr_p256(z1sq,z_1)
+        amontsqr_p256(z2sq,z_2)
+
+        montmul_p256(y1a,z_2,y_1)
+        montmul_p256(y2a,z_1,y_2)
+
+        montmul_p256(x2a,z1sq,x_2)
+        montmul_p256(x1a,z2sq,x_1)
+        montmul_p256(y2a,z1sq,y2a)
+        montmul_p256(y1a,z2sq,y1a)
+
+        sub_p256(xd,x2a,x1a)
+        sub_p256(yd,y2a,y1a)
+
+        amontsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x1a)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(xd,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y1a)
+
+        montmul_p256(resz,xd,z_2)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Load in the z coordinates of the inputs to check for P1 = 0 and P2 = 0
+// The condition codes get set by a comparison (P2 != 0) - (P1 != 0)
+// So "NBE" <=> ~(CF \/ ZF) <=> P1 = 0 /\ ~(P2 = 0)
+// and "B"  <=> CF          <=> ~(P1 = 0) /\ P2 = 0
+// and "Z"  <=> ZF          <=> (P1 = 0 <=> P2 = 0)
+
+        load4(%r8,%r9,%r10,%r11,z_1)
+
+        movq    %r8, %rax
+        movq    %r9, %rdx
+        orq     %r10, %rax
+        orq     %r11, %rdx
+        orq     %rdx, %rax
+        negq    %rax
+        sbbq    %rax, %rax
+
+        load4(%r12,%r13,%r14,%r15,z_2)
+
+        movq    %r12, %rbx
+        movq    %r13, %rdx
+        orq     %r14, %rbx
+        orq     %r15, %rdx
+        orq     %rdx, %rbx
+        negq    %rbx
+        sbbq    %rbx, %rbx
+
+        cmpq    %rax, %rbx
+
+// Multiplex the outputs accordingly, re-using the z's in registers
+
+        cmovbq  %r8, %r12
+        cmovbq  %r9, %r13
+        cmovbq  %r10, %r14
+        cmovbq  %r11, %r15
+
+        czload4(%r12,%r13,%r14,%r15,resz)
+
+        muxload4(%rax,%rbx,%rcx,%rdx,resx,x_1,x_2)
+        muxload4(%r8,%r9,%r10,%r11,resy,y_1,y_2)
+
+// Finally store back the multiplexed values
+
+        store4(x_3,%rax,%rbx,%rcx,%rdx)
+        store4(y_3,%r8,%r9,%r10,%r11)
+        store4(z_3,%r12,%r13,%r14,%r15)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjadd)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/x86_att/p256_montjadd_alt.S b/cbits/s2n/x86_att/p256_montjadd_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjadd_alt.S
@@ -0,0 +1,579 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjadd_alt(uint64_t p3[static 12],
+//                                  const uint64_t p1[static 12],
+//                                  const uint64_t p2[static 12]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1, RDX = p2
+// Microsoft x64 ABI:   RCX = p3, RDX = p1, R8 = p2
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjadd_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjadd_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjadd_alt)
+        .text
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs
+// These assume %rdi = p3, %rsi = p1 and %rbp = p2,
+// which needs to be set up explicitly before use.
+// The first two hold initially, and the second is
+// set up by copying the initial %rdx input to %rbp.
+// Thereafter, no code macro modifies any of them.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_2 0(%rbp)
+#define y_2 NUMSIZE(%rbp)
+#define z_2 (2*NUMSIZE)(%rbp)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// NSPACE is the total stack needed for these temporaries
+
+#define z1sq (NUMSIZE*0)(%rsp)
+#define ww (NUMSIZE*0)(%rsp)
+#define resx (NUMSIZE*0)(%rsp)
+
+#define yd (NUMSIZE*1)(%rsp)
+#define y2a (NUMSIZE*1)(%rsp)
+
+#define x2a (NUMSIZE*2)(%rsp)
+#define zzx2 (NUMSIZE*2)(%rsp)
+
+#define zz (NUMSIZE*3)(%rsp)
+#define t1 (NUMSIZE*3)(%rsp)
+
+#define t2 (NUMSIZE*4)(%rsp)
+#define x1a (NUMSIZE*4)(%rsp)
+#define zzx1 (NUMSIZE*4)(%rsp)
+#define resy (NUMSIZE*4)(%rsp)
+
+#define xd (NUMSIZE*5)(%rsp)
+#define z2sq (NUMSIZE*5)(%rsp)
+#define resz (NUMSIZE*5)(%rsp)
+
+#define y1a (NUMSIZE*6)(%rsp)
+
+#define NSPACE NUMSIZE*7
+
+// Corresponds exactly to bignum_montmul_p256_alt
+
+#define montmul_p256(P0,P1,P2)                  \
+        movq    P2, %rbx ;                      \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r9 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        xorl    %r10d, %r10d ;                     \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r11d, %r11d ;                     \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r12d, %r12d ;                     \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        movq    0x8+P2, %rbx ;                  \
+        xorl    %r13d, %r13d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        xorl    %r14d, %r14d ;                     \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        movq    0x10+P2, %rbx ;                 \
+        xorl    %r15d, %r15d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        adcq    %r15, %r15 ;                       \
+        movq    0x18+P2, %rbx ;                 \
+        xorl    %r8d, %r8d ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r8, %r8 ;                         \
+        xorl    %r9d, %r9d ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        decq    %rbx;                            \
+        adcq    %r13, %rbx ;                       \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rax ;                      \
+        movq    %rax, %rbx ;                       \
+        mulq    %rax;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r15 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        movq    %rax, %r9 ;                        \
+        movq    %rdx, %r10 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        movq    %rax, %r13 ;                       \
+        mulq    %rbx;                            \
+        movq    %rax, %r11 ;                       \
+        movq    %rdx, %r12 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        movq    %rax, %rbx ;                       \
+        mulq    %r13;                            \
+        movq    %rax, %r13 ;                       \
+        movq    %rdx, %r14 ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x18+P1, %rbx ;                 \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    $0x0, %r14 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    %r9, %r9 ;                         \
+        adcq    %r10, %r10 ;                       \
+        adcq    %r11, %r11 ;                       \
+        adcq    %r12, %r12 ;                       \
+        adcq    %r13, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        adcq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rax;                            \
+        addq    %r15, %r9 ;                        \
+        adcq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r14 ;                       \
+        adcq    %rcx, %rdx ;                       \
+        movq    %rdx, %r15 ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r8d, %r8d ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r8, %r14 ;                        \
+        adcq    %r8, %r15 ;                        \
+        adcq    %r8, %r8 ;                         \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r9d, %r9d ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        leaq    -0x1(%rbx), %rbx ;                 \
+        adcq    %r13, %rbx ;                       \
+        leaq    -0x1(%r9), %r9 ;                   \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Additional macros to help with final multiplexing
+
+#define load4(r0,r1,r2,r3,P)                    \
+        movq    P, r0 ;                        \
+        movq    8+P, r1 ;                      \
+        movq    16+P, r2 ;                     \
+        movq    24+P, r3
+
+#define store4(P,r0,r1,r2,r3)                   \
+        movq    r0, P ;                        \
+        movq    r1, 8+P ;                      \
+        movq    r2, 16+P ;                     \
+        movq    r3, 24+P
+
+#define czload4(r0,r1,r2,r3,P)                  \
+        cmovzq  P, r0 ;                        \
+        cmovzq  8+P, r1 ;                      \
+        cmovzq  16+P, r2 ;                     \
+        cmovzq  24+P, r3
+
+#define muxload4(r0,r1,r2,r3,P0,P1,P2)          \
+        movq    P0, r0 ;                       \
+        cmovbq  P1, r0 ;                       \
+        cmovnbe P2, r0 ;                       \
+        movq    8+P0, r1 ;                     \
+        cmovbq  8+P1, r1 ;                     \
+        cmovnbe 8+P2, r1 ;                     \
+        movq    16+P0, r2 ;                    \
+        cmovbq  16+P1, r2 ;                    \
+        cmovnbe 16+P2, r2 ;                    \
+        movq    24+P0, r3 ;                    \
+        cmovbq  24+P1, r3 ;                    \
+        cmovnbe 24+P2, r3
+
+S2N_BN_SYMBOL(p256_montjadd_alt):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        movq    %r8, %rdx
+#endif
+
+// Save registers and make room on stack for temporary variables
+// Put the input y in %rbp where it lasts as long as it's needed.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+        movq    %rdx, %rbp
+
+// Main code, just a sequence of basic field operations
+// 12 * multiply + 4 * square + 7 * subtract
+
+        montsqr_p256(z1sq,z_1)
+        montsqr_p256(z2sq,z_2)
+
+        montmul_p256(y1a,z_2,y_1)
+        montmul_p256(y2a,z_1,y_2)
+
+        montmul_p256(x2a,z1sq,x_2)
+        montmul_p256(x1a,z2sq,x_1)
+        montmul_p256(y2a,z1sq,y2a)
+        montmul_p256(y1a,z2sq,y1a)
+
+        sub_p256(xd,x2a,x1a)
+        sub_p256(yd,y2a,y1a)
+
+        montsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x1a)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(xd,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y1a)
+
+        montmul_p256(resz,xd,z_2)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Load in the z coordinates of the inputs to check for P1 = 0 and P2 = 0
+// The condition codes get set by a comparison (P2 != 0) - (P1 != 0)
+// So "NBE" <=> ~(CF \/ ZF) <=> P1 = 0 /\ ~(P2 = 0)
+// and "B"  <=> CF          <=> ~(P1 = 0) /\ P2 = 0
+// and "Z"  <=> ZF          <=> (P1 = 0 <=> P2 = 0)
+
+        load4(%r8,%r9,%r10,%r11,z_1)
+
+        movq    %r8, %rax
+        movq    %r9, %rdx
+        orq     %r10, %rax
+        orq     %r11, %rdx
+        orq     %rdx, %rax
+        negq    %rax
+        sbbq    %rax, %rax
+
+        load4(%r12,%r13,%r14,%r15,z_2)
+
+        movq    %r12, %rbx
+        movq    %r13, %rdx
+        orq     %r14, %rbx
+        orq     %r15, %rdx
+        orq     %rdx, %rbx
+        negq    %rbx
+        sbbq    %rbx, %rbx
+
+        cmpq    %rax, %rbx
+
+// Multiplex the outputs accordingly, re-using the z's in registers
+
+        cmovbq  %r8, %r12
+        cmovbq  %r9, %r13
+        cmovbq  %r10, %r14
+        cmovbq  %r11, %r15
+
+        czload4(%r12,%r13,%r14,%r15,resz)
+
+        muxload4(%rax,%rbx,%rcx,%rdx,resx,x_1,x_2)
+        muxload4(%r8,%r9,%r10,%r11,resy,y_1,y_2)
+
+// Finally store back the multiplexed values
+
+        store4(x_3,%rax,%rbx,%rcx,%rdx)
+        store4(y_3,%r8,%r9,%r10,%r11)
+        store4(z_3,%r12,%r13,%r14,%r15)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjadd_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/x86_att/p256_montjdouble.S b/cbits/s2n/x86_att/p256_montjdouble.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjdouble.S
@@ -0,0 +1,634 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjdouble(uint64_t p3[static 12],
+//                                 const uint64_t p1[static 12]);
+//
+// Does p3 := 2 * p1 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1
+// Microsoft x64 ABI:   RCX = p3, RDX = p1
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjdouble)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjdouble)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjdouble)
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs
+// These assume %rdi = p3, %rsi = p1, which is true when the
+// arguments come in initially and is not disturbed throughout.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// NSPACE is the total stack needed for these temporaries
+
+#define z2 (NUMSIZE*0)(%rsp)
+#define y4 (NUMSIZE*0)(%rsp)
+
+#define y2 (NUMSIZE*1)(%rsp)
+
+#define t1 (NUMSIZE*2)(%rsp)
+
+#define t2 (NUMSIZE*3)(%rsp)
+#define x2p (NUMSIZE*3)(%rsp)
+#define dx2 (NUMSIZE*3)(%rsp)
+
+#define xy2 (NUMSIZE*4)(%rsp)
+
+#define x4p (NUMSIZE*5)(%rsp)
+#define d (NUMSIZE*5)(%rsp)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds exactly to bignum_montmul_p256
+
+#define montmul_p256(P0,P1,P2)                  \
+        xorl    %r13d, %r13d ;                      \
+        movq    P2, %rdx ;                       \
+        mulxq   P1, %r8, %r9 ;                     \
+        mulxq   0x8+P1, %rbx, %r10 ;               \
+        adcq    %rbx, %r9 ;                         \
+        mulxq   0x10+P1, %rbx, %r11 ;              \
+        adcq    %rbx, %r10 ;                        \
+        mulxq   0x18+P1, %rbx, %r12 ;              \
+        adcq    %rbx, %r11 ;                        \
+        adcq    %r13, %r12 ;                        \
+        movq    0x8+P2, %rdx ;                   \
+        xorl    %r14d, %r14d ;                      \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcq    %r14, %r13 ;                        \
+        xorl    %r15d, %r15d ;                      \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %r15, %r13 ;                        \
+        adoxq   %r15, %r14 ;                        \
+        adcq    %r15, %r14 ;                        \
+        movq    0x10+P2, %rdx ;                  \
+        xorl    %r8d, %r8d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adoxq   %r8, %r14 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r13 ;                        \
+        adcq    %rbx, %r14 ;                        \
+        adcq    %r8, %r15 ;                         \
+        movq    0x18+P2, %rdx ;                  \
+        xorl    %r9d, %r9d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        adoxq   %r9, %r15 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r14 ;                        \
+        adcq    %rbx, %r15 ;                        \
+        adcq    %r9, %r8 ;                          \
+        xorl    %r9d, %r9d ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %r9, %r15 ;                         \
+        adoxq   %r9, %r8 ;                          \
+        adcq    %r9, %r8 ;                          \
+        movl    $0x1, %ecx ;                        \
+        addq    %r12, %rcx ;                        \
+        decq    %rdx;                            \
+        adcq    %r13, %rdx ;                        \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                         \
+        adcq    %r14, %r9 ;                         \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rcx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %r9, %r14 ;                         \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rdx ;                       \
+        mulxq   %rdx, %r8, %r15 ;                     \
+        mulxq   0x8+P1, %r9, %r10 ;                \
+        mulxq   0x18+P1, %r11, %r12 ;              \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   0x18+P1, %r13, %r14 ;              \
+        xorl    %ebp, %ebp ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rbp, %r13 ;                        \
+        adoxq   %rbp, %r14 ;                        \
+        adcq    %rbp, %r14 ;                        \
+        xorl    %ebp, %ebp ;                        \
+        adcxq   %r9, %r9 ;                          \
+        adoxq   %r15, %r9 ;                         \
+        movq    0x8+P1, %rdx ;                   \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r10, %r10 ;                        \
+        adoxq   %rax, %r10 ;                        \
+        adcxq   %r11, %r11 ;                        \
+        adoxq   %rdx, %r11 ;                        \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r12, %r12 ;                        \
+        adoxq   %rax, %r12 ;                        \
+        adcxq   %r13, %r13 ;                        \
+        adoxq   %rdx, %r13 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %r15 ;                    \
+        adcxq   %r14, %r14 ;                        \
+        adoxq   %rax, %r14 ;                        \
+        adcxq   %rbp, %r15 ;                        \
+        adoxq   %rbp, %r15 ;                        \
+        xorl    %ebp, %ebp ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rbp, %r13 ;                        \
+        movl    %ebp, %r9d ;                        \
+        adoxq   %rbp, %r9 ;                         \
+        adcxq   %rbp, %r9 ;                         \
+        addq    %r9, %r14 ;                         \
+        adcq    %rbp, %r15 ;                        \
+        movl    %ebp, %r8d ;                        \
+        adcq    %rbp, %r8 ;                         \
+        xorl    %ebp, %ebp ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %rbp, %r15 ;                        \
+        adoxq   %rbp, %r8 ;                         \
+        adcq    %rbp, %r8 ;                         \
+        movl    $0x1, %ecx ;                        \
+        addq    %r12, %rcx ;                        \
+        leaq    -0x1(%rdx), %rdx ;                  \
+        adcq    %r13, %rdx ;                        \
+        leaq    -0x1(%rbp), %rbp ;                  \
+        movq    %rbp, %rax ;                        \
+        adcq    %r14, %rbp ;                        \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rcx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %rbp, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Corresponds exactly to bignum_add_p256
+
+#define add_p256(P0,P1,P2)                      \
+        xorq    %r11, %r11 ;                        \
+        movq    P1, %rax ;                       \
+        addq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        adcq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        adcq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        adcq    0x18+P2, %r9 ;                   \
+        adcq    %r11, %r11 ;                        \
+        subq    $0xffffffffffffffff, %rax ;         \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r10, %rcx ;                        \
+        sbbq    $0x0, %r8 ;                         \
+        movq    $0xffffffff00000001, %rdx ;         \
+        sbbq    %rdx, %r9 ;                         \
+        sbbq    $0x0, %r11 ;                        \
+        andq    %r11, %r10 ;                        \
+        andq    %r11, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// A weak version of add that only guarantees sum in 4 digits
+
+#define weakadd_p256(P0,P1,P2)                  \
+        movq    P1, %rax ;                       \
+        addq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        adcq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        adcq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        adcq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        subq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        sbbq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        sbbq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        sbbq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// P0 = C * P1 - D * P2  computed as d * (p_256 - P2) + c * P1
+// Quotient estimation is done just as q = h + 1 as in bignum_triple_p256
+// This also applies to the other functions following.
+
+#define cmsub_p256(P0,C,P1,D,P2)                \
+        /* First (%r11;%r10;%r9;%r8) = p_256 - P2 */ \
+        movq    $0xffffffffffffffff, %r8 ;          \
+        xorl    %r10d, %r10d ;                      \
+        subq    P2, %r8 ;                        \
+        movq    $0x00000000ffffffff, %r9 ;          \
+        sbbq    0x8+P2, %r9 ;                    \
+        sbbq    0x10+P2, %r10 ;                  \
+        movq    $0xffffffff00000001, %r11 ;         \
+        sbbq    0x18+P2, %r11 ;                  \
+        /* (%r12;%r11;%r10;%r9;%r8) = D * (p_256 - P2) */  \
+        xorl    %r12d, %r12d ;                      \
+        movq    $D, %rdx ;                         \
+        mulxq   %r8, %r8, %rax ;                    \
+        mulxq   %r9, %r9, %rcx ;                    \
+        addq    %rax, %r9 ;                        \
+        mulxq   %r10, %r10, %rax ;                  \
+        adcq    %rcx, %r10 ;                       \
+        mulxq   %r11, %r11, %rcx ;                  \
+        adcq    %rax, %r11 ;                       \
+        adcq    %rcx, %r12 ;                       \
+        /* (%rdx;%r11;%r10;%r9;%r8) = 2^256 + C * P1 + D * (p_256 - P2) */ \
+        movq    $C, %rdx ;                         \
+        xorl    %eax, %eax ;                       \
+        mulxq   P1, %rax, %rcx ;                 \
+        adcxq   %rax, %r8 ;                        \
+        adoxq   %rcx, %r9 ;                        \
+        mulxq   0x8+P1, %rax, %rcx ;             \
+        adcxq   %rax, %r9 ;                        \
+        adoxq   %rcx, %r10 ;                       \
+        mulxq   0x10+P1, %rax, %rcx ;            \
+        adcxq   %rax, %r10 ;                       \
+        adoxq   %rcx, %r11 ;                       \
+        mulxq   0x18+P1, %rax, %rdx ;            \
+        adcxq   %rax, %r11 ;                       \
+        adoxq   %r12, %rdx ;                       \
+        adcq    $1, %rdx ;                         \
+        /* Now the tail for modular reduction from tripling */ \
+        addq    %rdx, %r8 ;                         \
+        movq    $0x100000000, %rax ;                \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    $0x0, %rax ;                        \
+        sbbq    $0x0, %rcx ;                        \
+        subq    %rax, %r9 ;                         \
+        sbbq    %rcx, %r10 ;                        \
+        movq    $0xffffffff00000001, %rax ;         \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    %rax, %r11 ;                        \
+        sbbq    %rcx, %rdx ;                        \
+        decq    %rdx;                            \
+        movl    $0xffffffff, %eax ;                 \
+        andq    %rdx, %rax ;                        \
+        xorl    %ecx, %ecx ;                        \
+        subq    %rax, %rcx ;                        \
+        addq    %rdx, %r8 ;                         \
+        movq    %r8, P0 ;                        \
+        adcq    %rax, %r9 ;                         \
+        movq    %r9, 0x8+P0 ;                    \
+        adcq    $0x0, %r10 ;                        \
+        movq    %r10, 0x10+P0 ;                  \
+        adcq    %rcx, %r11 ;                        \
+        movq    %r11, 0x18+P0
+
+// P0 = 3 * P1 - 8 * P2, computed as (p_256 - P2) << 3 + 3 * P1
+
+#define cmsub38_p256(P0,P1,P2)                  \
+        /* First (%r11;%r10;%r9;%r8) = p_256 - P2 */ \
+        movq    $0xffffffffffffffff, %r8 ;          \
+        xorl    %r10d, %r10d ;                      \
+        subq    P2, %r8 ;                        \
+        movq    $0x00000000ffffffff, %r9 ;          \
+        sbbq    0x8+P2, %r9 ;                    \
+        sbbq    0x10+P2, %r10 ;                  \
+        movq    $0xffffffff00000001, %r11 ;         \
+        sbbq    0x18+P2, %r11 ;                  \
+        /* (%r12;%r11;%r10;%r9;%r8) = (p_256 - P2) << 3 */  \
+        movq    %r11, %r12 ;                       \
+        shldq   $3, %r10, %r11 ;                    \
+        shldq   $3, %r9, %r10 ;                     \
+        shldq   $3, %r8, %r9 ;                      \
+        shlq    $3, %r8 ;                          \
+        shrq    $61, %r12 ;                        \
+        /* (%rdx;%r11;%r10;%r9;%r8) = 2^256 + 3 * P1 + 8 * (p_256 - P2) */ \
+        movq    $3, %rdx ;                         \
+        xorl    %eax, %eax ;                       \
+        mulxq   P1, %rax, %rcx ;                 \
+        adcxq   %rax, %r8 ;                        \
+        adoxq   %rcx, %r9 ;                        \
+        mulxq   0x8+P1, %rax, %rcx ;             \
+        adcxq   %rax, %r9 ;                        \
+        adoxq   %rcx, %r10 ;                       \
+        mulxq   0x10+P1, %rax, %rcx ;            \
+        adcxq   %rax, %r10 ;                       \
+        adoxq   %rcx, %r11 ;                       \
+        mulxq   0x18+P1, %rax, %rdx ;            \
+        adcxq   %rax, %r11 ;                       \
+        adoxq   %r12, %rdx ;                       \
+        adcq    $1, %rdx ;                         \
+        /* Now the tail for modular reduction from tripling */ \
+        addq    %rdx, %r8 ;                         \
+        movq    $0x100000000, %rax ;                \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    $0x0, %rax ;                        \
+        sbbq    $0x0, %rcx ;                        \
+        subq    %rax, %r9 ;                         \
+        sbbq    %rcx, %r10 ;                        \
+        movq    $0xffffffff00000001, %rax ;         \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    %rax, %r11 ;                        \
+        sbbq    %rcx, %rdx ;                        \
+        decq    %rdx;                            \
+        movl    $0xffffffff, %eax ;                 \
+        andq    %rdx, %rax ;                        \
+        xorl    %ecx, %ecx ;                        \
+        subq    %rax, %rcx ;                        \
+        addq    %rdx, %r8 ;                         \
+        movq    %r8, P0 ;                        \
+        adcq    %rax, %r9 ;                         \
+        movq    %r9, 0x8+P0 ;                    \
+        adcq    $0x0, %r10 ;                        \
+        movq    %r10, 0x10+P0 ;                  \
+        adcq    %rcx, %r11 ;                        \
+        movq    %r11, 0x18+P0
+
+// P0 = 4 * P1 - P2, by direct subtraction of P2,
+// since the quotient estimate still works safely
+// for initial value > -p_256
+
+#define cmsub41_p256(P0,P1,P2)                  \
+        movq    0x18+P1, %r11 ;                  \
+        movq    %r11, %rdx ;                       \
+        movq    0x10+P1, %r10 ;                  \
+        shldq   $2, %r10, %r11 ;                    \
+        movq    0x8+P1, %r9 ;                    \
+        shldq   $2, %r9, %r10 ;                     \
+        movq    P1, %r8 ;                        \
+        shldq   $2, %r8, %r9 ;                      \
+        shlq    $2, %r8 ;                          \
+        shrq    $62, %rdx ;                        \
+        addq    $1, %rdx ;                         \
+        subq    P2, %r8 ;                       \
+        sbbq    0x8+P2, %r9 ;                   \
+        sbbq    0x10+P2, %r10 ;                 \
+        sbbq    0x18+P2, %r11 ;                 \
+        sbbq    $0, %rdx ;                         \
+        /* Now the tail for modular reduction from tripling */ \
+        addq    %rdx, %r8 ;                         \
+        movq    $0x100000000, %rax ;                \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    $0x0, %rax ;                        \
+        sbbq    $0x0, %rcx ;                        \
+        subq    %rax, %r9 ;                         \
+        sbbq    %rcx, %r10 ;                        \
+        movq    $0xffffffff00000001, %rax ;         \
+        mulxq   %rax, %rax, %rcx ;                    \
+        sbbq    %rax, %r11 ;                        \
+        sbbq    %rcx, %rdx ;                        \
+        decq    %rdx;                            \
+        movl    $0xffffffff, %eax ;                 \
+        andq    %rdx, %rax ;                        \
+        xorl    %ecx, %ecx ;                        \
+        subq    %rax, %rcx ;                        \
+        addq    %rdx, %r8 ;                         \
+        movq    %r8, P0 ;                        \
+        adcq    %rax, %r9 ;                         \
+        movq    %r9, 0x8+P0 ;                    \
+        adcq    $0x0, %r10 ;                        \
+        movq    %r10, 0x10+P0 ;                  \
+        adcq    %rcx, %r11 ;                        \
+        movq    %r11, 0x18+P0
+
+S2N_BN_SYMBOL(p256_montjdouble):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Save registers and make room on stack for temporary variables
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+// Main code, just a sequence of basic field operations
+
+// z2 = z^2
+// y2 = y^2
+
+        montsqr_p256(z2,z_1)
+        montsqr_p256(y2,y_1)
+
+// x2p = x^2 - z^4 = (x + z^2) * (x - z^2)
+
+        sub_p256(t2,x_1,z2)
+        weakadd_p256(t1,x_1,z2)
+        montmul_p256(x2p,t1,t2)
+
+// t1 = y + z
+// xy2 = x * y^2
+// x4p = x2p^2
+
+        add_p256(t1,y_1,z_1)
+        montmul_p256(xy2,x_1,y2)
+        montsqr_p256(x4p,x2p)
+
+// t1 = (y + z)^2
+
+        montsqr_p256(t1,t1)
+
+// d = 12 * xy2 - 9 * x4p
+// t1 = y^2 + 2 * y * z
+
+        cmsub_p256(d,12,xy2,9,x4p)
+        sub_p256(t1,t1,z2)
+
+// y4 = y^4
+
+        montsqr_p256(y4,y2)
+
+// dx2 = d * x2p
+
+        montmul_p256(dx2,d,x2p)
+
+// z_3' = 2 * y * z
+
+        sub_p256(z_3,t1,y2)
+
+// x' = 4 * xy2 - d
+
+        cmsub41_p256(x_3,xy2,d)
+
+// y' = 3 * dx2 - 8 * y4
+
+        cmsub38_p256(y_3,dx2,y4)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjdouble)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/x86_att/p256_montjdouble_alt.S b/cbits/s2n/x86_att/p256_montjdouble_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjdouble_alt.S
@@ -0,0 +1,747 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjdouble_alt(uint64_t p3[static 12],
+//                                     const uint64_t p1[static 12]);
+//
+// Does p3 := 2 * p1 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1
+// Microsoft x64 ABI:   RCX = p3, RDX = p1
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjdouble_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjdouble_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjdouble_alt)
+        .text
+        .balign 4
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs
+// These assume %rdi = p3, %rsi = p1, which is true when the
+// arguments come in initially and is not disturbed throughout.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing
+// NSPACE is the total stack needed for these temporaries
+
+#define z2 (NUMSIZE*0)(%rsp)
+#define y4 (NUMSIZE*0)(%rsp)
+
+#define y2 (NUMSIZE*1)(%rsp)
+
+#define t1 (NUMSIZE*2)(%rsp)
+
+#define t2 (NUMSIZE*3)(%rsp)
+#define x2p (NUMSIZE*3)(%rsp)
+#define dx2 (NUMSIZE*3)(%rsp)
+
+#define xy2 (NUMSIZE*4)(%rsp)
+
+#define x4p (NUMSIZE*5)(%rsp)
+#define d (NUMSIZE*5)(%rsp)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds exactly to bignum_montmul_p256_alt
+
+#define montmul_p256(P0,P1,P2)                  \
+        movq    P2, %rbx ;                      \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r9 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        xorl    %r10d, %r10d ;                     \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r11d, %r11d ;                     \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r12d, %r12d ;                     \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        movq    0x8+P2, %rbx ;                  \
+        xorl    %r13d, %r13d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        xorl    %r14d, %r14d ;                     \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        movq    0x10+P2, %rbx ;                 \
+        xorl    %r15d, %r15d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        adcq    %r15, %r15 ;                       \
+        movq    0x18+P2, %rbx ;                 \
+        xorl    %r8d, %r8d ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r8, %r8 ;                         \
+        xorl    %r9d, %r9d ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        decq    %rbx;                            \
+        adcq    %r13, %rbx ;                       \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rax ;                      \
+        movq    %rax, %rbx ;                       \
+        mulq    %rax;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r15 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        movq    %rax, %r9 ;                        \
+        movq    %rdx, %r10 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        movq    %rax, %r13 ;                       \
+        mulq    %rbx;                            \
+        movq    %rax, %r11 ;                       \
+        movq    %rdx, %r12 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        movq    %rax, %rbx ;                       \
+        mulq    %r13;                            \
+        movq    %rax, %r13 ;                       \
+        movq    %rdx, %r14 ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x18+P1, %rbx ;                 \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    $0x0, %r14 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    %r9, %r9 ;                         \
+        adcq    %r10, %r10 ;                       \
+        adcq    %r11, %r11 ;                       \
+        adcq    %r12, %r12 ;                       \
+        adcq    %r13, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        adcq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rax;                            \
+        addq    %r15, %r9 ;                        \
+        adcq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r14 ;                       \
+        adcq    %rcx, %rdx ;                       \
+        movq    %rdx, %r15 ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r8d, %r8d ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r8, %r14 ;                        \
+        adcq    %r8, %r15 ;                        \
+        adcq    %r8, %r8 ;                         \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r9d, %r9d ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        leaq    -0x1(%rbx), %rbx ;                 \
+        adcq    %r13, %rbx ;                       \
+        leaq    -0x1(%r9), %r9 ;                   \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Corresponds exactly to bignum_add_p256
+
+#define add_p256(P0,P1,P2)                      \
+        xorq    %r11, %r11 ;                        \
+        movq    P1, %rax ;                       \
+        addq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        adcq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        adcq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        adcq    0x18+P2, %r9 ;                   \
+        adcq    %r11, %r11 ;                        \
+        subq    $0xffffffffffffffff, %rax ;         \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r10, %rcx ;                        \
+        sbbq    $0x0, %r8 ;                         \
+        movq    $0xffffffff00000001, %rdx ;         \
+        sbbq    %rdx, %r9 ;                         \
+        sbbq    $0x0, %r11 ;                        \
+        andq    %r11, %r10 ;                        \
+        andq    %r11, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// A weak version of add that only guarantees sum in 4 digits
+
+#define weakadd_p256(P0,P1,P2)                  \
+        movq    P1, %rax ;                       \
+        addq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        adcq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        adcq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        adcq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        subq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        sbbq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        sbbq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        sbbq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// P0 = C * P1 - D * P2  computed as d * (p_256 - P2) + c * P1
+// Quotient estimation is done just as q = h + 1 as in bignum_triple_p256_alt.
+// This also applies to the other functions following.
+
+#define cmsub_p256(P0,C,P1,D,P2)                \
+        /* First (%r12;%r11;%r10;%r9) = p_256 - P2 */ \
+        movq    $0xffffffffffffffff, %r9 ;          \
+        xorl    %r11d, %r11d ;                      \
+        subq    P2, %r9 ;                        \
+        movq    $0x00000000ffffffff, %r10 ;         \
+        sbbq    0x8+P2, %r10 ;                   \
+        sbbq    0x10+P2, %r11 ;                  \
+        movq    $0xffffffff00000001, %r12 ;         \
+        sbbq    0x18+P2, %r12 ;                  \
+        /* (%r12;%r11;%r10;%r9;%r8) = D * (p_256 - P2) */  \
+        movq    $D, %rcx ;                         \
+        movq    %r9, %rax ;                        \
+        mulq    %rcx;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r9 ;                        \
+        movq    %r10, %rax ;                       \
+        xorl    %r10d, %r10d ;                     \
+        mulq    %rcx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        movq    %r11, %rax ;                       \
+        xorl    %r11d, %r11d ;                     \
+        mulq    %rcx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        movq    %r12, %rax ;                       \
+        xorl    %r12d, %r12d ;                     \
+        mulq    %rcx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        /* (%rcx;%r11;%r10;%r9;%r8) = 2^256 + C * P1 + D * (p_256 - P2) */ \
+        movl    $C, %ecx ;                         \
+        movq    P1, %rax ;                      \
+        mulq    %rcx;                            \
+        addq    %rax, %r8 ;                        \
+        adcq    %rdx, %r9 ;                        \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        leaq    1(%r12), %rcx ;                   \
+        /* Now the tail for modular reduction from tripling */ \
+        movq    $0xffffffff00000001, %rax ;        \
+        mulq    %rcx;                            \
+        movq    %rcx, %rbx ;                       \
+        shlq    $0x20, %rbx ;                      \
+        addq    %rcx, %r8 ;                        \
+        sbbq    $0x0, %rbx ;                       \
+        subq    %rbx, %r9 ;                        \
+        sbbq    $0x0, %r10 ;                       \
+        sbbq    %rax, %r11 ;                       \
+        sbbq    %rdx, %rcx ;                       \
+        decq    %rcx;                            \
+        movl    $0xffffffff, %eax ;                \
+        andq    %rcx, %rax ;                       \
+        xorl    %edx, %edx ;                       \
+        subq    %rax, %rdx ;                       \
+        addq    %rcx, %r8 ;                        \
+        movq    %r8, P0 ;                       \
+        adcq    %rax, %r9 ;                        \
+        movq    %r9, 0x8+P0 ;                   \
+        adcq    $0x0, %r10 ;                       \
+        movq    %r10, 0x10+P0 ;                 \
+        adcq    %rdx, %r11 ;                       \
+        movq    %r11, 0x18+P0
+
+// P0 = 3 * P1 - 8 * P2, computed as (p_256 - P2) << 3 + 3 * P1
+
+#define cmsub38_p256(P0,P1,P2)                  \
+        /* First (%r11;%r10;%r9;%r8) = p_256 - P2 */ \
+        movq    $0xffffffffffffffff, %r8 ;          \
+        xorl    %r10d, %r10d ;                      \
+        subq    P2, %r8 ;                        \
+        movq    $0x00000000ffffffff, %r9 ;          \
+        sbbq    0x8+P2, %r9 ;                    \
+        sbbq    0x10+P2, %r10 ;                  \
+        movq    $0xffffffff00000001, %r11 ;         \
+        sbbq    0x18+P2, %r11 ;                  \
+        /* (%r12;%r11;%r10;%r9;%r8) = (p_256 - P2) << 3 */  \
+        movq    %r11, %r12 ;                       \
+        shldq   $3, %r10, %r11 ;                    \
+        shldq   $3, %r9, %r10 ;                     \
+        shldq   $3, %r8, %r9 ;                      \
+        shlq    $3, %r8 ;                          \
+        shrq    $61, %r12 ;                        \
+        /* (%rcx;%r11;%r10;%r9;%r8) = 2^256 + 3 * P1 + 8 * (p_256 - P2) */ \
+        movl    $3, %ecx ;                         \
+        movq    P1, %rax ;                      \
+        mulq    %rcx;                            \
+        addq    %rax, %r8 ;                        \
+        adcq    %rdx, %r9 ;                        \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rbx, %rbx ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rcx;                            \
+        subq    %rbx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        leaq    1(%r12), %rcx ;                   \
+        /* Now the tail for modular reduction from tripling */ \
+        movq    $0xffffffff00000001, %rax ;        \
+        mulq    %rcx;                            \
+        movq    %rcx, %rbx ;                       \
+        shlq    $0x20, %rbx ;                      \
+        addq    %rcx, %r8 ;                        \
+        sbbq    $0x0, %rbx ;                       \
+        subq    %rbx, %r9 ;                        \
+        sbbq    $0x0, %r10 ;                       \
+        sbbq    %rax, %r11 ;                       \
+        sbbq    %rdx, %rcx ;                       \
+        decq    %rcx;                            \
+        movl    $0xffffffff, %eax ;                \
+        andq    %rcx, %rax ;                       \
+        xorl    %edx, %edx ;                       \
+        subq    %rax, %rdx ;                       \
+        addq    %rcx, %r8 ;                        \
+        movq    %r8, P0 ;                       \
+        adcq    %rax, %r9 ;                        \
+        movq    %r9, 0x8+P0 ;                   \
+        adcq    $0x0, %r10 ;                       \
+        movq    %r10, 0x10+P0 ;                 \
+        adcq    %rdx, %r11 ;                       \
+        movq    %r11, 0x18+P0
+
+// P0 = 4 * P1 - P2, by direct subtraction of P2,
+// since the quotient estimate still works safely
+// for initial value > -p_256
+
+#define cmsub41_p256(P0,P1,P2)                  \
+        movq    0x18+P1, %r11 ;                  \
+        movq    %r11, %rcx ;                       \
+        movq    0x10+P1, %r10 ;                  \
+        shldq   $2, %r10, %r11 ;                    \
+        movq    0x8+P1, %r9 ;                    \
+        shldq   $2, %r9, %r10 ;                     \
+        movq    P1, %r8 ;                        \
+        shldq   $2, %r8, %r9 ;                      \
+        shlq    $2, %r8 ;                          \
+        shrq    $62, %rcx ;                        \
+        addq    $1, %rcx ;                         \
+        subq    P2, %r8 ;                       \
+        sbbq    0x8+P2, %r9 ;                   \
+        sbbq    0x10+P2, %r10 ;                 \
+        sbbq    0x18+P2, %r11 ;                 \
+        sbbq    $0, %rcx ;                         \
+        /* Now the tail for modular reduction from tripling */ \
+        movq    $0xffffffff00000001, %rax ;        \
+        mulq    %rcx;                            \
+        movq    %rcx, %rbx ;                       \
+        shlq    $0x20, %rbx ;                      \
+        addq    %rcx, %r8 ;                        \
+        sbbq    $0x0, %rbx ;                       \
+        subq    %rbx, %r9 ;                        \
+        sbbq    $0x0, %r10 ;                       \
+        sbbq    %rax, %r11 ;                       \
+        sbbq    %rdx, %rcx ;                       \
+        decq    %rcx;                            \
+        movl    $0xffffffff, %eax ;                \
+        andq    %rcx, %rax ;                       \
+        xorl    %edx, %edx ;                       \
+        subq    %rax, %rdx ;                       \
+        addq    %rcx, %r8 ;                        \
+        movq    %r8, P0 ;                       \
+        adcq    %rax, %r9 ;                        \
+        movq    %r9, 0x8+P0 ;                   \
+        adcq    $0x0, %r10 ;                       \
+        movq    %r10, 0x10+P0 ;                 \
+        adcq    %rdx, %r11 ;                       \
+        movq    %r11, 0x18+P0
+
+S2N_BN_SYMBOL(p256_montjdouble_alt):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+#endif
+
+// Save registers and make room on stack for temporary variables
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+// Main code, just a sequence of basic field operations
+
+// z2 = z^2
+// y2 = y^2
+
+        montsqr_p256(z2,z_1)
+        montsqr_p256(y2,y_1)
+
+// x2p = x^2 - z^4 = (x + z^2) * (x - z^2)
+
+        sub_p256(t2,x_1,z2)
+        weakadd_p256(t1,x_1,z2)
+        montmul_p256(x2p,t1,t2)
+
+// t1 = y + z
+// xy2 = x * y^2
+// x4p = x2p^2
+
+        add_p256(t1,y_1,z_1)
+        montmul_p256(xy2,x_1,y2)
+        montsqr_p256(x4p,x2p)
+
+// t1 = (y + z)^2
+
+        montsqr_p256(t1,t1)
+
+// d = 12 * xy2 - 9 * x4p
+// t1 = y^2 + 2 * y * z
+
+        cmsub_p256(d,12,xy2,9,x4p)
+        sub_p256(t1,t1,z2)
+
+// y4 = y^4
+
+        montsqr_p256(y4,y2)
+
+// dx2 = d * x2p
+
+        montmul_p256(dx2,d,x2p)
+
+// z_3' = 2 * y * z
+
+        sub_p256(z_3,t1,y2)
+
+// x' = 4 * xy2 - d
+
+        cmsub41_p256(x_3,xy2,d)
+
+// y' = 3 * dx2 - 8 * y4
+
+        cmsub38_p256(y_3,dx2,y4)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjdouble_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/x86_att/p256_montjmixadd.S b/cbits/s2n/x86_att/p256_montjmixadd.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjmixadd.S
@@ -0,0 +1,567 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjmixadd(uint64_t p3[static 12],
+//                                 const uint64_t p1[static 12],
+//                                 const uint64_t p2[static 8]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+// The "mixed" part means that p2 only has x and y coordinates, with the
+// implicit z coordinate assumed to be the identity.
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1, RDX = p2
+// Microsoft x64 ABI:   RCX = p3, RDX = p1, R8 = p2
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjmixadd)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjmixadd)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjmixadd)
+        .text
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs.
+// These assume %rdi = p3, %rsi = p1 and %rbp = p2,
+// which needs to be set up explicitly before use.
+// The first two hold initially, and the second is
+// set up by copying the initial %rdx input to %rbp.
+// Thereafter, no code macro modifies any of them.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_2 0(%rbp)
+#define y_2 NUMSIZE(%rbp)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing.
+// NSPACE is the total stack needed for all temporaries.
+
+#define zp2 (NUMSIZE*0)(%rsp)
+#define ww (NUMSIZE*0)(%rsp)
+#define resx (NUMSIZE*0)(%rsp)
+
+#define yd (NUMSIZE*1)(%rsp)
+#define y2a (NUMSIZE*1)(%rsp)
+
+#define x2a (NUMSIZE*2)(%rsp)
+#define zzx2 (NUMSIZE*2)(%rsp)
+
+#define zz (NUMSIZE*3)(%rsp)
+#define t1 (NUMSIZE*3)(%rsp)
+
+#define t2 (NUMSIZE*4)(%rsp)
+#define zzx1 (NUMSIZE*4)(%rsp)
+#define resy (NUMSIZE*4)(%rsp)
+
+#define xd (NUMSIZE*5)(%rsp)
+#define resz (NUMSIZE*5)(%rsp)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds exactly to bignum_montmul_p256
+
+#define montmul_p256(P0,P1,P2)                  \
+        xorl    %r13d, %r13d ;                      \
+        movq    P2, %rdx ;                       \
+        mulxq   P1, %r8, %r9 ;                     \
+        mulxq   0x8+P1, %rbx, %r10 ;               \
+        adcq    %rbx, %r9 ;                         \
+        mulxq   0x10+P1, %rbx, %r11 ;              \
+        adcq    %rbx, %r10 ;                        \
+        mulxq   0x18+P1, %rbx, %r12 ;              \
+        adcq    %rbx, %r11 ;                        \
+        adcq    %r13, %r12 ;                        \
+        movq    0x8+P2, %rdx ;                   \
+        xorl    %r14d, %r14d ;                      \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcq    %r14, %r13 ;                        \
+        xorl    %r15d, %r15d ;                      \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %r15, %r13 ;                        \
+        adoxq   %r15, %r14 ;                        \
+        adcq    %r15, %r14 ;                        \
+        movq    0x10+P2, %rdx ;                  \
+        xorl    %r8d, %r8d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adoxq   %r8, %r14 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r13 ;                        \
+        adcq    %rbx, %r14 ;                        \
+        adcq    %r8, %r15 ;                         \
+        movq    0x18+P2, %rdx ;                  \
+        xorl    %r9d, %r9d ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        mulxq   0x10+P1, %rax, %rbx ;              \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        adoxq   %r9, %r15 ;                         \
+        mulxq   0x18+P1, %rax, %rbx ;              \
+        adcq    %rax, %r14 ;                        \
+        adcq    %rbx, %r15 ;                        \
+        adcq    %r9, %r8 ;                          \
+        xorl    %r9d, %r9d ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        notq    %rdx;                            \
+        leaq    0x2(%rdx), %rdx ;                  \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %r9, %r15 ;                         \
+        adoxq   %r9, %r8 ;                          \
+        adcq    %r9, %r8 ;                          \
+        movl    $0x1, %ecx ;                        \
+        addq    %r12, %rcx ;                        \
+        decq    %rdx;                            \
+        adcq    %r13, %rdx ;                        \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                         \
+        adcq    %r14, %r9 ;                         \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rcx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %r9, %r14 ;                         \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256 except for
+// register tweaks to avoid modifying %rbp.
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rdx ;                       \
+        mulxq   %rdx, %r8, %r15 ;                     \
+        mulxq   0x8+P1, %r9, %r10 ;                \
+        mulxq   0x18+P1, %r11, %r12 ;              \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   0x18+P1, %r13, %r14 ;              \
+        xorl    %ecx, %ecx ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        adoxq   %rcx, %r14 ;                        \
+        adcq    %rcx, %r14 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        adcxq   %r9, %r9 ;                          \
+        adoxq   %r15, %r9 ;                         \
+        movq    0x8+P1, %rdx ;                   \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r10, %r10 ;                        \
+        adoxq   %rax, %r10 ;                        \
+        adcxq   %r11, %r11 ;                        \
+        adoxq   %rdx, %r11 ;                        \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r12, %r12 ;                        \
+        adoxq   %rax, %r12 ;                        \
+        adcxq   %r13, %r13 ;                        \
+        adoxq   %rdx, %r13 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %r15 ;                    \
+        adcxq   %r14, %r14 ;                        \
+        adoxq   %rax, %r14 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r15 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        movl    %ecx, %r9d ;                        \
+        adoxq   %rcx, %r9 ;                         \
+        adcxq   %rcx, %r9 ;                         \
+        addq    %r9, %r14 ;                         \
+        adcq    %rcx, %r15 ;                        \
+        movl    %ecx, %r8d ;                        \
+        adcq    %rcx, %r8 ;                         \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r8 ;                         \
+        adcq    %rcx, %r8 ;                         \
+        movl    $0x1, %ebx ;                        \
+        addq    %r12, %rbx ;                        \
+        leaq    -0x1(%rdx), %rdx ;                  \
+        adcq    %r13, %rdx ;                        \
+        leaq    -0x1(%rcx), %rcx ;                  \
+        movq    %rcx, %rax ;                        \
+        adcq    %r14, %rcx ;                        \
+        movl    $0xfffffffe, %r11d ;                \
+        adcq    %r15, %r11 ;                        \
+        adcq    %r8, %rax ;                         \
+        cmovbq  %rbx, %r12 ;                        \
+        cmovbq  %rdx, %r13 ;                        \
+        cmovbq  %rcx, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Almost-Montgomery variant which we use when an input to other muls
+// with the other argument fully reduced (which is always safe).
+// Again, the basic squaring code is tweaked to avoid modifying %rbp.
+
+#define amontsqr_p256(P0,P1)                    \
+        movq    P1, %rdx ;                       \
+        mulxq   %rdx, %r8, %r15 ;                     \
+        mulxq   0x8+P1, %r9, %r10 ;                \
+        mulxq   0x18+P1, %r11, %r12 ;              \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   0x18+P1, %r13, %r14 ;              \
+        xorl    %ecx, %ecx ;                        \
+        mulxq   P1, %rax, %rbx ;                   \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   0x8+P1, %rax, %rbx ;               \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        adoxq   %rcx, %r14 ;                        \
+        adcq    %rcx, %r14 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        adcxq   %r9, %r9 ;                          \
+        adoxq   %r15, %r9 ;                         \
+        movq    0x8+P1, %rdx ;                   \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r10, %r10 ;                        \
+        adoxq   %rax, %r10 ;                        \
+        adcxq   %r11, %r11 ;                        \
+        adoxq   %rdx, %r11 ;                        \
+        movq    0x10+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %rdx ;                    \
+        adcxq   %r12, %r12 ;                        \
+        adoxq   %rax, %r12 ;                        \
+        adcxq   %r13, %r13 ;                        \
+        adoxq   %rdx, %r13 ;                        \
+        movq    0x18+P1, %rdx ;                  \
+        mulxq   %rdx, %rax, %r15 ;                    \
+        adcxq   %r14, %r14 ;                        \
+        adoxq   %rax, %r14 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r15 ;                        \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r9 ;                         \
+        adoxq   %rbx, %r10 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r10 ;                        \
+        adoxq   %rbx, %r11 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r8, %rax, %rbx ;                     \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r9, %rax, %rbx ;                     \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        adcxq   %rcx, %r13 ;                        \
+        movl    %ecx, %r9d ;                        \
+        adoxq   %rcx, %r9 ;                         \
+        adcxq   %rcx, %r9 ;                         \
+        addq    %r9, %r14 ;                         \
+        adcq    %rcx, %r15 ;                        \
+        movl    %ecx, %r8d ;                        \
+        adcq    %rcx, %r8 ;                         \
+        xorl    %ecx, %ecx ;                        \
+        movabsq $0x100000000, %rdx ;                \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r11 ;                        \
+        adoxq   %rbx, %r12 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r12 ;                        \
+        adoxq   %rbx, %r13 ;                        \
+        movabsq $0xffffffff00000001, %rdx ;         \
+        mulxq   %r10, %rax, %rbx ;                    \
+        adcxq   %rax, %r13 ;                        \
+        adoxq   %rbx, %r14 ;                        \
+        mulxq   %r11, %rax, %rbx ;                    \
+        adcxq   %rax, %r14 ;                        \
+        adoxq   %rbx, %r15 ;                        \
+        adcxq   %rcx, %r15 ;                        \
+        adoxq   %rcx, %r8 ;                         \
+        adcq    %rcx, %r8 ;                         \
+        movl    $0x1, %r8d ;                        \
+        leaq    -0x1(%rdx), %rdx ;                  \
+        leaq    -0x1(%rcx), %rax ;                  \
+        movl    $0xfffffffe, %r11d ;                \
+        cmovzq  %rcx, %r8 ;                         \
+        cmovzq  %rcx, %rdx ;                        \
+        cmovzq  %rcx, %rax ;                        \
+        cmovzq  %rcx, %r11 ;                        \
+        addq    %r8, %r12 ;                         \
+        adcq    %rdx, %r13 ;                        \
+        adcq    %rax, %r14 ;                        \
+        adcq    %r11, %r15 ;                        \
+        movq    %r12, P0 ;                       \
+        movq    %r13, 0x8+P0 ;                   \
+        movq    %r14, 0x10+P0 ;                  \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Additional macros to help with final multiplexing
+
+#define testzero4(P)                            \
+        movq    P, %rax ;                       \
+        movq    8+P, %rdx ;                     \
+        orq     16+P, %rax ;                    \
+        orq     24+P, %rdx ;                    \
+        orq     %rdx, %rax
+
+#define mux4(r0,r1,r2,r3,PNE,PEQ)               \
+        movq    PNE, r0 ;                      \
+        movq    PEQ, %rax ;                     \
+        cmovzq  %rax, r0 ;                        \
+        movq    8+PNE, r1 ;                    \
+        movq    8+PEQ, %rax ;                   \
+        cmovzq  %rax, r1 ;                        \
+        movq    16+PNE, r2 ;                   \
+        movq    16+PEQ, %rax ;                  \
+        cmovzq  %rax, r2 ;                        \
+        movq    24+PNE, r3 ;                   \
+        movq    24+PEQ, %rax ;                  \
+        cmovzq  %rax, r3
+
+#define load4(r0,r1,r2,r3,P)                    \
+        movq    P, r0 ;                        \
+        movq    8+P, r1 ;                      \
+        movq    16+P, r2 ;                     \
+        movq    24+P, r3
+
+#define store4(P,r0,r1,r2,r3)                   \
+        movq    r0, P ;                        \
+        movq    r1, 8+P ;                      \
+        movq    r2, 16+P ;                     \
+        movq    r3, 24+P
+
+S2N_BN_SYMBOL(p256_montjmixadd):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        movq    %r8, %rdx
+#endif
+
+// Save registers and make room on stack for temporary variables
+// Put the input y in %rbp where it lasts as long as it's needed.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+        movq    %rdx, %rbp
+
+// Main code, just a sequence of basic field operations
+// 8 * multiply + 3 * square + 7 * subtract
+
+        amontsqr_p256(zp2,z_1)
+
+        montmul_p256(y2a,z_1,y_2)
+        montmul_p256(x2a,zp2,x_2)
+        montmul_p256(y2a,zp2,y2a)
+
+        sub_p256(xd,x2a,x_1)
+
+        sub_p256(yd,y2a,y_1)
+
+        amontsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x_1)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(resz,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y_1)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Test if z_1 = 0 to decide if p1 = 0 (up to projective equivalence)
+
+        testzero4(z_1)
+
+// Multiplex: if p1 <> 0 just copy the computed result from the staging area.
+// If p1 = 0 then return the point p2 augmented with a z = 1 coordinate (in
+// Montgomery form so not the simple constant 1 but rather 2^256 - p_256),
+// hence giving 0 + p2 = p2 for the final result.
+
+        mux4(%r8,%r9,%r10,%r11,resx,x_2)
+        mux4(%r12,%r13,%r14,%r15,resy,y_2)
+
+        store4(x_3,%r8,%r9,%r10,%r11)
+        store4(y_3,%r12,%r13,%r14,%r15)
+
+        load4(%r8,%r9,%r10,%r11,resz)
+        movl    $1, %eax
+        cmovzq  %rax, %r8
+        movq    $0xffffffff00000000, %rax
+        cmovzq  %rax, %r9
+        movq    $0xffffffffffffffff, %rax
+        cmovzq  %rax, %r10
+        movl    $0x00000000fffffffe, %eax
+        cmovzq  %rax, %r11
+
+        store4(z_3,%r8,%r9,%r10,%r11)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjmixadd)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/s2n/x86_att/p256_montjmixadd_alt.S b/cbits/s2n/x86_att/p256_montjmixadd_alt.S
new file mode 100644
--- /dev/null
+++ b/cbits/s2n/x86_att/p256_montjmixadd_alt.S
@@ -0,0 +1,552 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
+
+// ----------------------------------------------------------------------------
+// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
+//
+//    extern void p256_montjmixadd_alt(uint64_t p3[static 12],
+//                                     const uint64_t p1[static 12],
+//                                     const uint64_t p2[static 8]);
+//
+// Does p3 := p1 + p2 where all points are regarded as Jacobian triples with
+// each coordinate in the Montgomery domain, i.e. x' = (2^256 * x) mod p_256.
+// A Jacobian triple (x',y',z') represents affine point (x/z^2,y/z^3).
+// The "mixed" part means that p2 only has x and y coordinates, with the
+// implicit z coordinate assumed to be the identity.
+//
+// Standard x86-64 ABI: RDI = p3, RSI = p1, RDX = p2
+// Microsoft x64 ABI:   RCX = p3, RDX = p1, R8 = p2
+// ----------------------------------------------------------------------------
+#include "_internal_s2n_bignum_x86_att.h"
+
+
+        S2N_BN_SYM_VISIBILITY_DIRECTIVE(p256_montjmixadd_alt)
+        S2N_BN_FUNCTION_TYPE_DIRECTIVE(p256_montjmixadd_alt)
+        S2N_BN_SYM_PRIVACY_DIRECTIVE(p256_montjmixadd_alt)
+        .text
+
+// Size of individual field elements
+
+#define NUMSIZE 32
+
+// Pointer-offset pairs for inputs and outputs.
+// These assume %rdi = p3, %rsi = p1 and %rbp = p2,
+// which needs to be set up explicitly before use.
+// The first two hold initially, and the second is
+// set up by copying the initial %rdx input to %rbp.
+// Thereafter, no code macro modifies any of them.
+
+#define x_1 0(%rsi)
+#define y_1 NUMSIZE(%rsi)
+#define z_1 (2*NUMSIZE)(%rsi)
+
+#define x_2 0(%rbp)
+#define y_2 NUMSIZE(%rbp)
+
+#define x_3 0(%rdi)
+#define y_3 NUMSIZE(%rdi)
+#define z_3 (2*NUMSIZE)(%rdi)
+
+// Pointer-offset pairs for temporaries, with some aliasing.
+// NSPACE is the total stack needed for all temporaries.
+
+#define zp2 (NUMSIZE*0)(%rsp)
+#define ww (NUMSIZE*0)(%rsp)
+#define resx (NUMSIZE*0)(%rsp)
+
+#define yd (NUMSIZE*1)(%rsp)
+#define y2a (NUMSIZE*1)(%rsp)
+
+#define x2a (NUMSIZE*2)(%rsp)
+#define zzx2 (NUMSIZE*2)(%rsp)
+
+#define zz (NUMSIZE*3)(%rsp)
+#define t1 (NUMSIZE*3)(%rsp)
+
+#define t2 (NUMSIZE*4)(%rsp)
+#define zzx1 (NUMSIZE*4)(%rsp)
+#define resy (NUMSIZE*4)(%rsp)
+
+#define xd (NUMSIZE*5)(%rsp)
+#define resz (NUMSIZE*5)(%rsp)
+
+#define NSPACE NUMSIZE*6
+
+// Corresponds exactly to bignum_montmul_p256_alt
+
+#define montmul_p256(P0,P1,P2)                  \
+        movq    P2, %rbx ;                      \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r9 ;                        \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        xorl    %r10d, %r10d ;                     \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r11d, %r11d ;                     \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        xorl    %r12d, %r12d ;                     \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        movq    0x8+P2, %rbx ;                  \
+        xorl    %r13d, %r13d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r14, %r14 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r14, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        xorl    %r14d, %r14d ;                     \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %r15, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        movq    0x10+P2, %rbx ;                 \
+        xorl    %r15d, %r15d ;                     \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r8, %r8 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r8, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        adcq    %r15, %r15 ;                       \
+        movq    0x18+P2, %rbx ;                 \
+        xorl    %r8d, %r8d ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %r9, %r9 ;                         \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rbx;                            \
+        subq    %r9, %rdx ;                        \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r8, %r8 ;                         \
+        xorl    %r9d, %r9d ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        decq    %rbx;                            \
+        adcq    %r13, %rbx ;                       \
+        decq    %r9;                             \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_montsqr_p256_alt
+
+#define montsqr_p256(P0,P1)                     \
+        movq    P1, %rax ;                      \
+        movq    %rax, %rbx ;                       \
+        mulq    %rax;                            \
+        movq    %rax, %r8 ;                        \
+        movq    %rdx, %r15 ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        movq    %rax, %r9 ;                        \
+        movq    %rdx, %r10 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        movq    %rax, %r13 ;                       \
+        mulq    %rbx;                            \
+        movq    %rax, %r11 ;                       \
+        movq    %rdx, %r12 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        movq    %rax, %rbx ;                       \
+        mulq    %r13;                            \
+        movq    %rax, %r13 ;                       \
+        movq    %rdx, %r14 ;                       \
+        movq    P1, %rax ;                      \
+        mulq    %rbx;                            \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    0x18+P1, %rbx ;                 \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    $0x0, %r14 ;                       \
+        xorl    %ecx, %ecx ;                       \
+        addq    %r9, %r9 ;                         \
+        adcq    %r10, %r10 ;                       \
+        adcq    %r11, %r11 ;                       \
+        adcq    %r12, %r12 ;                       \
+        adcq    %r13, %r13 ;                       \
+        adcq    %r14, %r14 ;                       \
+        adcq    %rcx, %rcx ;                       \
+        movq    0x8+P1, %rax ;                  \
+        mulq    %rax;                            \
+        addq    %r15, %r9 ;                        \
+        adcq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x10+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %r15, %r15 ;                       \
+        movq    0x18+P1, %rax ;                 \
+        mulq    %rax;                            \
+        negq    %r15;                            \
+        adcq    %rax, %r14 ;                       \
+        adcq    %rcx, %rdx ;                       \
+        movq    %rdx, %r15 ;                       \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        addq    %rax, %r9 ;                        \
+        adcq    %rdx, %r10 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r10 ;                       \
+        adcq    %rdx, %r11 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r8, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r8d, %r8d ;                       \
+        movq    %r9, %rax ;                        \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        adcq    %r8, %r14 ;                        \
+        adcq    %r8, %r15 ;                        \
+        adcq    %r8, %r8 ;                         \
+        movq    $0x100000000, %rbx ;               \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        addq    %rax, %r11 ;                       \
+        adcq    %rdx, %r12 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r12 ;                       \
+        adcq    %rdx, %r13 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        notq    %rbx;                            \
+        leaq    0x2(%rbx), %rbx ;                 \
+        movq    %r10, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r13 ;                       \
+        adcq    %rdx, %r14 ;                       \
+        sbbq    %rcx, %rcx ;                       \
+        xorl    %r9d, %r9d ;                       \
+        movq    %r11, %rax ;                       \
+        mulq    %rbx;                            \
+        subq    %rcx, %rdx ;                       \
+        addq    %rax, %r14 ;                       \
+        adcq    %rdx, %r15 ;                       \
+        adcq    %r9, %r8 ;                         \
+        movl    $0x1, %ecx ;                       \
+        addq    %r12, %rcx ;                       \
+        leaq    -0x1(%rbx), %rbx ;                 \
+        adcq    %r13, %rbx ;                       \
+        leaq    -0x1(%r9), %r9 ;                   \
+        movq    %r9, %rax ;                        \
+        adcq    %r14, %r9 ;                        \
+        movl    $0xfffffffe, %r11d ;               \
+        adcq    %r15, %r11 ;                       \
+        adcq    %r8, %rax ;                        \
+        cmovbq  %rcx, %r12 ;                       \
+        cmovbq  %rbx, %r13 ;                       \
+        cmovbq  %r9, %r14 ;                        \
+        cmovbq  %r11, %r15 ;                       \
+        movq    %r12, P0 ;                      \
+        movq    %r13, 0x8+P0 ;                  \
+        movq    %r14, 0x10+P0 ;                 \
+        movq    %r15, 0x18+P0
+
+// Corresponds exactly to bignum_sub_p256
+
+#define sub_p256(P0,P1,P2)                      \
+        movq    P1, %rax ;                       \
+        subq    P2, %rax ;                       \
+        movq    0x8+P1, %rcx ;                   \
+        sbbq    0x8+P2, %rcx ;                   \
+        movq    0x10+P1, %r8 ;                   \
+        sbbq    0x10+P2, %r8 ;                   \
+        movq    0x18+P1, %r9 ;                   \
+        sbbq    0x18+P2, %r9 ;                   \
+        movl    $0xffffffff, %r10d ;                \
+        sbbq    %r11, %r11 ;                        \
+        xorq    %rdx, %rdx ;                        \
+        andq    %r11, %r10 ;                        \
+        subq    %r10, %rdx ;                        \
+        addq    %r11, %rax ;                        \
+        movq    %rax, P0 ;                       \
+        adcq    %r10, %rcx ;                        \
+        movq    %rcx, 0x8+P0 ;                   \
+        adcq    $0x0, %r8 ;                         \
+        movq    %r8, 0x10+P0 ;                   \
+        adcq    %rdx, %r9 ;                         \
+        movq    %r9, 0x18+P0
+
+// Additional macros to help with final multiplexing
+
+#define testzero4(P)                            \
+        movq    P, %rax ;                       \
+        movq    8+P, %rdx ;                     \
+        orq     16+P, %rax ;                    \
+        orq     24+P, %rdx ;                    \
+        orq     %rdx, %rax
+
+#define mux4(r0,r1,r2,r3,PNE,PEQ)               \
+        movq    PNE, r0 ;                      \
+        movq    PEQ, %rax ;                     \
+        cmovzq  %rax, r0 ;                        \
+        movq    8+PNE, r1 ;                    \
+        movq    8+PEQ, %rax ;                   \
+        cmovzq  %rax, r1 ;                        \
+        movq    16+PNE, r2 ;                   \
+        movq    16+PEQ, %rax ;                  \
+        cmovzq  %rax, r2 ;                        \
+        movq    24+PNE, r3 ;                   \
+        movq    24+PEQ, %rax ;                  \
+        cmovzq  %rax, r3
+
+#define load4(r0,r1,r2,r3,P)                    \
+        movq    P, r0 ;                        \
+        movq    8+P, r1 ;                      \
+        movq    16+P, r2 ;                     \
+        movq    24+P, r3
+
+#define store4(P,r0,r1,r2,r3)                   \
+        movq    r0, P ;                        \
+        movq    r1, 8+P ;                      \
+        movq    r2, 16+P ;                     \
+        movq    r3, 24+P
+
+S2N_BN_SYMBOL(p256_montjmixadd_alt):
+        CFI_START
+        _CET_ENDBR
+
+#if WINDOWS_ABI
+        CFI_PUSH(%rdi)
+        CFI_PUSH(%rsi)
+        movq    %rcx, %rdi
+        movq    %rdx, %rsi
+        movq    %r8, %rdx
+#endif
+
+// Save registers and make room on stack for temporary variables
+// Put the input y in %rbp where it lasts as long as it's needed.
+
+        CFI_PUSH(%rbx)
+        CFI_PUSH(%rbp)
+        CFI_PUSH(%r12)
+        CFI_PUSH(%r13)
+        CFI_PUSH(%r14)
+        CFI_PUSH(%r15)
+
+        CFI_DEC_RSP(NSPACE)
+
+        movq    %rdx, %rbp
+
+// Main code, just a sequence of basic field operations
+// 8 * multiply + 3 * square + 7 * subtract
+
+        montsqr_p256(zp2,z_1)
+
+        montmul_p256(y2a,z_1,y_2)
+        montmul_p256(x2a,zp2,x_2)
+        montmul_p256(y2a,zp2,y2a)
+
+        sub_p256(xd,x2a,x_1)
+
+        sub_p256(yd,y2a,y_1)
+
+        montsqr_p256(zz,xd)
+        montsqr_p256(ww,yd)
+
+        montmul_p256(zzx1,zz,x_1)
+        montmul_p256(zzx2,zz,x2a)
+
+        sub_p256(resx,ww,zzx1)
+        sub_p256(t1,zzx2,zzx1)
+
+        montmul_p256(resz,xd,z_1)
+
+        sub_p256(resx,resx,zzx2)
+
+        sub_p256(t2,zzx1,resx)
+
+        montmul_p256(t1,t1,y_1)
+        montmul_p256(t2,yd,t2)
+
+        sub_p256(resy,t2,t1)
+
+// Test if z_1 = 0 to decide if p1 = 0 (up to projective equivalence)
+
+        testzero4(z_1)
+
+// Multiplex: if p1 <> 0 just copy the computed result from the staging area.
+// If p1 = 0 then return the point p2 augmented with a z = 1 coordinate (in
+// Montgomery form so not the simple constant 1 but rather 2^256 - p_256),
+// hence giving 0 + p2 = p2 for the final result.
+
+        mux4(%r8,%r9,%r10,%r11,resx,x_2)
+        mux4(%r12,%r13,%r14,%r15,resy,y_2)
+
+        store4(x_3,%r8,%r9,%r10,%r11)
+        store4(y_3,%r12,%r13,%r14,%r15)
+
+        load4(%r8,%r9,%r10,%r11,resz)
+        movl    $1, %eax
+        cmovzq  %rax, %r8
+        movq    $0xffffffff00000000, %rax
+        cmovzq  %rax, %r9
+        movq    $0xffffffffffffffff, %rax
+        cmovzq  %rax, %r10
+        movl    $0x00000000fffffffe, %eax
+        cmovzq  %rax, %r11
+
+        store4(z_3,%r8,%r9,%r10,%r11)
+
+// Restore stack and registers
+
+        CFI_INC_RSP(NSPACE)
+        CFI_POP(%r15)
+        CFI_POP(%r14)
+        CFI_POP(%r13)
+        CFI_POP(%r12)
+        CFI_POP(%rbp)
+        CFI_POP(%rbx)
+
+#if WINDOWS_ABI
+        CFI_POP(%rsi)
+        CFI_POP(%rdi)
+#endif
+        CFI_RET
+
+S2N_BN_SIZE_DIRECTIVE(p256_montjmixadd_alt)
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", %progbits
+#endif
diff --git a/cbits/sha1_armv8.c b/cbits/sha1_armv8.c
--- a/cbits/sha1_armv8.c
+++ b/cbits/sha1_armv8.c
@@ -72,15 +72,15 @@
 	e0 = state[4];
 
 	for (; blocks > 0; blocks--, data += 64) {
-	const uint32_t *buf = (const uint32_t *) data;
+	const uint8_t *buf = data;
 
 	abcd_prev = abcd;
 	e_prev = e0;
 
-	m0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf))));
-	m1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 4))));
-	m2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 8))));
-	m3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 12))));
+	m0 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf)));
+	m1 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 16)));
+	m2 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 32)));
+	m3 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 48)));
 
 	wk0 = vaddq_u32(m0, k0);
 	wk1 = vaddq_u32(m1, k0);
@@ -151,7 +151,7 @@
 }
 
 /* the one-block form, for the partial block a message ends with */
-void crypton_sha1_armv8_do_chunk(uint32_t state[5], const uint32_t buf[16])
+void crypton_sha1_armv8_do_chunk(uint32_t state[5], const uint8_t buf[64])
 {
 	crypton_sha1_armv8_do_chunks(state, (const uint8_t *) buf, 1);
 }
diff --git a/cbits/sha256_armv8.c b/cbits/sha256_armv8.c
--- a/cbits/sha256_armv8.c
+++ b/cbits/sha256_armv8.c
@@ -59,7 +59,7 @@
  * order, `buf` the block as it arrived, which SHA-256 reads big-endian.
  */
 TARGET_ARMV8_CRYPTO
-void crypton_sha256_armv8_do_chunk(uint32_t state[8], const uint32_t buf[16])
+void crypton_sha256_armv8_do_chunk(uint32_t state[8], const uint8_t buf[64])
 {
 	uint32x4_t abcd, efgh, abcd_prev, efgh_prev, abcd_save, tmp;
 	uint32x4_t m0, m1, m2, m3;
@@ -68,10 +68,10 @@
 	abcd_prev = abcd = vld1q_u32(state);
 	efgh_prev = efgh = vld1q_u32(state + 4);
 
-	m0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf))));
-	m1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 4))));
-	m2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 8))));
-	m3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(vld1q_u32(buf + 12))));
+	m0 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf)));
+	m1 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 16)));
+	m2 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 32)));
+	m3 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(buf + 48)));
 
 	/* twelve groups of four rounds that also extend the schedule ... */
 	for (i = 0; i < 48; i += 16) {
diff --git a/cbits/sha512_armv8.c b/cbits/sha512_armv8.c
--- a/cbits/sha512_armv8.c
+++ b/cbits/sha512_armv8.c
@@ -73,7 +73,7 @@
  * to the start; a group of eight steps is one pass over the schedule.
  */
 TARGET_ARMV8_SHA3
-void crypton_sha512_armv8_do_chunk(uint64_t state[8], const uint64_t buf[16])
+void crypton_sha512_armv8_do_chunk(uint64_t state[8], const uint8_t buf[128])
 {
 	uint64x2_t ab, cd, ef, gh, ab0, cd0, ef0, gh0;
 	uint64x2_t s[8];
@@ -86,7 +86,7 @@
 
 	for (i = 0; i < 8; i++)
 		s[i] = vreinterpretq_u64_u8(vrev64q_u8(
-		    vld1q_u8((const uint8_t *) (buf + 2 * i))));
+		    vld1q_u8(buf + 16 * i)));
 
 /* two rounds; A, B, C, D is a rotation of gh, ef, cd, ab */
 #define RND(A, B, C, D, sv, ki)                                             \
diff --git a/cbits/tests/ct/README b/cbits/tests/ct/README
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/README
@@ -0,0 +1,70 @@
+Does the code that handles a secret run in time independent of it?
+
+memcheck already follows undefined bytes through arithmetic and reports the
+moment one of them decides a branch or an address.  That is the same question,
+so each driver here declares its secret undefined and runs under valgrind:
+every report names a place where a secret reached a branch or an index.  The
+technique is Adam Langley's ctgrind.
+
+ct_canary.c is the calibration.  It branches on a secret and indexes a table
+with one, so it must report; if it does not, the marking is not reaching the
+code and the silence of every other driver in that run means nothing.  Round
+five learned this the hard way with ThreadSanitizer, which saw nothing through
+GHC's runtime including a deliberate race.
+
+What is marked secret in each driver is the thing the caller would call a
+private key, and nothing else.  A modulus, a peer's public key, a nonce and a
+message are public and stay defined; so does each answer, which is declared
+public again before anything looks at it.
+
+  canary   a branch and a table index on a secret -- must report
+  powm     crypton_powm_sec, the exponent being an RSA private key
+  p256     both scalar multiplications and the scalar inversion
+  x25519   the scalar
+  ed25519  the private key, through signing
+  decaf    Ed448 signing and X448, both private scalars
+  chapoly  the ChaCha20 key, the plaintext, and the Poly1305 key
+  aes      the AES key and the plaintext, through ECB and GCM
+
+The aes driver is built against cbits/aes/generic.c and cbits/aes/gf.c on
+purpose, rather than whatever the machine offers.  AES-NI and the ARMv8
+instructions do not look anything up and would report nothing, which would say
+nothing about the table-driven code every other machine runs.  That code is
+variable-time by construction -- a table index is a byte of the state -- and
+so is the table-driven GHASH beside it.  A report from the aes driver is
+therefore expected and is a property of those implementations, not a defect
+found in them; it is here so that the size of it is written down rather than
+assumed.  Everything else is expected to be silent.
+
+What round eight found
+----------------------
+
+Of the eight drivers, five were silent: the RSA exponentiation, X25519,
+Ed25519, ChaCha20 and Poly1305 never let a private key decide a branch or an
+address.  The AES driver reported from the tables, as it was built to.
+
+The other two reported, five places between them, and every one of them an
+assert():
+
+  crypton_p256_modmul          assert(top <= 1), assert(top == 0)
+  crypton_gf_448_strong_reduce two asserts on a carry and a borrow
+  crypton_gf_invert            assert(ret), that what was inverted had an
+                               inverse
+
+The first four check an invariant of a reduction rather than anything about
+the data, so they hold whatever the input is.  The fifth holds because the two
+callers that ask for it are inverting a projective z, which is never zero for
+a point on the curve.  Either way the branch goes the same way every time and
+no timing follows from it.  They are reported at all because
+crypton's C is compiled without NDEBUG, so assert() is live in a released
+library.  Twenty-eight assertions ship that way, none of them with a side
+effect, and defining NDEBUG measured no faster on P-256, so whether to keep
+them is a question about what a library should do when an internal invariant
+fails -- abort the process, or carry on -- rather than one about speed.  They
+are listed in known.txt and the job passes with them.
+
+The decision was to keep them: an internal invariant that fails in a
+cryptographic library is better met with an abort than with a wrong answer
+carried onwards.  So this is settled rather than open, and the five entries in
+known.txt are permanent.  What is not permanent is anything else appearing
+beside them.
diff --git a/cbits/tests/ct/ct.h b/cbits/tests/ct/ct.h
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct.h
@@ -0,0 +1,53 @@
+/* Marking secrets for valgrind.
+ *
+ * memcheck already follows undefined bytes through arithmetic and complains
+ * the moment one decides a branch or an address.  That is the same question
+ * as "does this run in time independent of the secret", so a secret declared
+ * undefined turns memcheck into a checker for it.  The technique is Adam
+ * Langley's ctgrind.
+ *
+ * Without CRYPTON_CT_VALGRIND the macros vanish and the drivers still build
+ * and run, which is how they are kept honest on a machine with no valgrind.
+ */
+#ifndef CRYPTON_TESTS_CT_H
+#define CRYPTON_TESTS_CT_H
+
+#ifdef CRYPTON_CT_VALGRIND
+#include <valgrind/memcheck.h>
+/* this memory is a secret: report any branch or index that depends on it */
+#define CT_SECRET(p, n) VALGRIND_MAKE_MEM_UNDEFINED((p), (n))
+/* and this is the answer, which the caller is allowed to look at */
+#define CT_PUBLIC(p, n) VALGRIND_MAKE_MEM_DEFINED((p), (n))
+#else
+#define CT_SECRET(p, n) ((void)(p), (void)(n))
+#define CT_PUBLIC(p, n) ((void)(p), (void)(n))
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+
+/* A deterministic filler, so that a report names the same operation on every
+ * run.  It is not random and does not need to be. */
+static uint64_t ct_s0 = 0x243f6a8885a308d3ULL, ct_s1 = 0x13198a2e03707344ULL;
+static uint64_t ct_rnd(void) {
+    uint64_t x = ct_s0, y = ct_s1;
+    ct_s0 = y;
+    x ^= x << 23;
+    ct_s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
+    return ct_s1 + y;
+}
+static void ct_fill(void *p, size_t n) {
+    uint8_t *q = (uint8_t *)p;
+    size_t i;
+    for (i = 0; i < n; i++) q[i] = (uint8_t)(ct_rnd() >> 24);
+}
+/* Look at the answer, so that nothing above is optimized away.  Whatever is
+ * handed here has been declared public first. */
+static void ct_sink(const void *p, size_t n) {
+    const uint8_t *q = (const uint8_t *)p;
+    size_t i;
+    uint8_t acc = 0;
+    for (i = 0; i < n; i++) acc ^= q[i];
+    if (acc == 0xa5 && n == (size_t)-1) printf("unreachable\n");
+}
+#endif
diff --git a/cbits/tests/ct/ct_aes.c b/cbits/tests/ct/ct_aes.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_aes.c
@@ -0,0 +1,35 @@
+/* AES, and AES-GCM.  The key is the secret, and so is the plaintext.
+ *
+ * Whether this reports depends on which implementation the machine selected.
+ * AES-NI and the ARMv8 instructions do not look anything up; the generic C
+ * is table-driven and is variable-time by construction, which is a property
+ * of that code rather than a defect in it.  See cbits/tests/ct/README. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "crypton_aes.h"
+
+int main(void) {
+    aes_key k;
+    aes_gcm_key gk;
+    uint8_t key[32], pt[256], ct[256 + 16], iv[12];
+
+    ct_fill(key, sizeof key);
+    ct_fill(pt, sizeof pt);
+    ct_fill(iv, sizeof iv);
+    CT_SECRET(key, sizeof key);
+    CT_SECRET(pt, sizeof pt);
+
+    crypton_aes_initkey(&k, key, sizeof key);
+    crypton_aes_encrypt_ecb((aes_block *)ct, &k, (aes_block *)pt,
+                            sizeof pt / 16);
+    CT_PUBLIC(ct, sizeof pt);
+    ct_sink(ct, sizeof pt);
+
+    crypton_aes_gcm_key_init(&gk, &k);
+    /* the output takes the ciphertext and then the tag */
+    crypton_aes_gcm_full_encrypt(ct, &gk, &k, iv, sizeof iv, NULL, 0,
+                                 pt, sizeof pt, 16);
+    CT_PUBLIC(ct, sizeof ct);
+    ct_sink(ct, sizeof ct);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_canary.c b/cbits/tests/ct/ct_canary.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_canary.c
@@ -0,0 +1,21 @@
+/* The calibration.  This one is deliberately not constant time: it branches
+ * on a secret byte and indexes a table with another.  If it reports nothing,
+ * the marking is not reaching the code and every other driver's silence in
+ * this run means nothing either -- which is the whole reason it is here. */
+#include "tests/ct/ct.h"
+
+static const uint8_t table[256] = {1};
+
+int main(void) {
+    uint8_t secret[32], out[2];
+
+    ct_fill(secret, sizeof secret);
+    CT_SECRET(secret, sizeof secret);
+
+    out[0] = secret[0] & 1 ? 0x5a : 0xa5;   /* a branch on the secret */
+    out[1] = table[secret[1]];              /* an address from the secret */
+
+    CT_PUBLIC(out, sizeof out);
+    ct_sink(out, sizeof out);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_chapoly.c b/cbits/tests/ct/ct_chapoly.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_chapoly.c
@@ -0,0 +1,33 @@
+/* ChaCha20 and Poly1305.  The key is the secret, and so is the plaintext. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "crypton_chacha.h"
+#include "crypton_poly1305.h"
+
+int main(void) {
+    crypton_chacha_context ctx;
+    poly1305_ctx pctx;
+    poly1305_key pkey;
+    poly1305_mac mac;
+    uint8_t key[32], iv[12], pt[256], ct[256];
+
+    ct_fill(key, sizeof key);
+    ct_fill(iv, sizeof iv);
+    ct_fill(pt, sizeof pt);
+    ct_fill(pkey, sizeof pkey);
+    CT_SECRET(key, sizeof key);
+    CT_SECRET(pt, sizeof pt);
+    CT_SECRET(pkey, sizeof pkey);
+
+    crypton_chacha_init(&ctx, 20, sizeof key, key, sizeof iv, iv);
+    crypton_chacha_combine(ct, &ctx, pt, sizeof pt);
+    CT_PUBLIC(ct, sizeof ct);          /* the ciphertext goes on the wire */
+    ct_sink(ct, sizeof ct);
+
+    crypton_poly1305_init(&pctx, &pkey);
+    crypton_poly1305_update(&pctx, ct, sizeof ct);
+    crypton_poly1305_finalize(mac, &pctx);
+    CT_PUBLIC(mac, sizeof mac);
+    ct_sink(mac, sizeof mac);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_decaf.c b/cbits/tests/ct/ct_decaf.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_decaf.c
@@ -0,0 +1,36 @@
+/* X448 and Ed448.  The scalar and the private key are the secrets. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "decaf/ed448.h"
+#include "decaf/point_448.h"
+
+int main(void) {
+    uint8_t priv[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES];
+    uint8_t pub[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES];
+    uint8_t sig[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES];
+    uint8_t xs[CRYPTON_DECAF_X448_PRIVATE_BYTES];
+    uint8_t xb[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+    uint8_t xo[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+    uint8_t msg[64];
+
+    ct_fill(priv, sizeof priv);
+    ct_fill(msg, sizeof msg);
+    ct_fill(xs, sizeof xs);
+    ct_fill(xb, sizeof xb);
+    CT_SECRET(priv, sizeof priv);
+    CT_SECRET(xs, sizeof xs);
+
+    crypton_decaf_ed448_derive_public_key(pub, priv);
+    CT_PUBLIC(pub, sizeof pub);
+    crypton_decaf_ed448_sign(sig, priv, pub, msg, sizeof msg, 0, NULL, 0);
+    CT_PUBLIC(sig, sizeof sig);
+    ct_sink(sig, sizeof sig);
+
+    crypton_decaf_x448_derive_public_key(xo, xs);
+    CT_PUBLIC(xo, sizeof xo);
+    ct_sink(xo, sizeof xo);
+    (void)crypton_decaf_x448(xo, xb, xs);
+    CT_PUBLIC(xo, sizeof xo);
+    ct_sink(xo, sizeof xo);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_ed25519.c b/cbits/tests/ct/ct_ed25519.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_ed25519.c
@@ -0,0 +1,23 @@
+/* Ed25519 signing.  The private key is the secret; the message is not. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "ed25519/ed25519.h"
+
+int main(void) {
+    ed25519_secret_key sk;
+    ed25519_public_key pk;
+    ed25519_signature sig;
+    uint8_t msg[64];
+
+    ct_fill(sk, sizeof sk);
+    ct_fill(msg, sizeof msg);
+    CT_SECRET(sk, sizeof sk);
+
+    crypton_ed25519_publickey(sk, pk);
+    CT_PUBLIC(pk, sizeof pk);
+
+    crypton_ed25519_sign(msg, sizeof msg, sk, pk, sig);
+    CT_PUBLIC(sig, sizeof sig);
+    ct_sink(sig, sizeof sig);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_p256.c b/cbits/tests/ct/ct_p256.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_p256.c
@@ -0,0 +1,42 @@
+/* The two P-256 scalar multiplications and the scalar inversion, all of
+ * which take the private key as the scalar. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "p256/p256.h"
+
+void crypton_p256e_point_mul(const crypton_p256_int *n,
+    const crypton_p256_int *ix, const crypton_p256_int *iy,
+    crypton_p256_int *ox, crypton_p256_int *oy);
+void crypton_p256e_scalar_invert(const crypton_p256_int *a,
+                                 crypton_p256_int *b);
+
+int main(void) {
+    crypton_p256_int n, px, py, ox, oy, inv, one;
+    int i;
+
+    /* a public point to be multiplied: the generator's 0x9e3779b9 multiple */
+    crypton_p256_init(&one);
+    P256_DIGIT(&one, 0) = 0x9e3779b9u;
+    crypton_p256_base_point_mul(&one, &px, &py);
+
+    for (i = 0; i < P256_NDIGITS; i++)
+        P256_DIGIT(&n, i) = (crypton_p256_digit)ct_rnd();
+    crypton_p256_mod(&crypton_SECP256r1_n, &n, &n);
+
+    CT_SECRET(&n, sizeof n);
+
+    crypton_p256_base_point_mul(&n, &ox, &oy);
+    CT_PUBLIC(&ox, sizeof ox);
+    CT_PUBLIC(&oy, sizeof oy);
+    ct_sink(&ox, sizeof ox);
+
+    crypton_p256e_point_mul(&n, &px, &py, &ox, &oy);
+    CT_PUBLIC(&ox, sizeof ox);
+    CT_PUBLIC(&oy, sizeof oy);
+    ct_sink(&oy, sizeof oy);
+
+    crypton_p256e_scalar_invert(&n, &inv);
+    CT_PUBLIC(&inv, sizeof inv);
+    ct_sink(&inv, sizeof inv);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_powm.c b/cbits/tests/ct/ct_powm.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_powm.c
@@ -0,0 +1,29 @@
+/* The windowed modular exponentiation, which is what an RSA private key
+ * operation runs.  The exponent is the secret it is built to hide. */
+#include "tests/ct/ct.h"
+#include <string.h>
+#include "crypton_powm.h"
+
+int main(void) {
+    enum { LEN = 256 };                 /* a 2048-bit modulus */
+    uint8_t out[LEN], base[LEN], mod[LEN], exp[LEN];
+
+    ct_fill(base, sizeof base);
+    ct_fill(mod, sizeof mod);
+    ct_fill(exp, sizeof exp);
+    mod[0] |= 0x80;                     /* full width */
+    mod[LEN - 1] |= 1;                  /* and odd, which is what it wants */
+    base[0] &= 0x7f;                    /* below the modulus */
+
+    /* The exponent is the private key.  The base is the ciphertext, which an
+     * attacker chooses and already knows, so it stays public. */
+    CT_SECRET(exp, sizeof exp);
+
+    if (crypton_powm_sec(out, base, LEN, exp, LEN, mod, LEN) != 0) {
+        printf("powm_sec refused\n");
+        return 1;
+    }
+    CT_PUBLIC(out, sizeof out);
+    ct_sink(out, sizeof out);
+    return 0;
+}
diff --git a/cbits/tests/ct/ct_x25519.c b/cbits/tests/ct/ct_x25519.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/ct_x25519.c
@@ -0,0 +1,25 @@
+/* X25519.  The scalar is the private key; the base point is the peer's
+ * public key and is not secret. */
+#include "tests/ct/ct.h"
+#include <string.h>
+
+void crypton_curve25519_donna(uint8_t *mypublic, const uint8_t *secret,
+                              const uint8_t *basepoint);
+
+int main(void) {
+    uint8_t sec[32], base[32], out[32];
+    static const uint8_t g[32] = {9};
+
+    ct_fill(sec, sizeof sec);
+    ct_fill(base, sizeof base);
+    CT_SECRET(sec, sizeof sec);
+
+    crypton_curve25519_donna(out, sec, g);       /* the public key */
+    CT_PUBLIC(out, sizeof out);
+    ct_sink(out, sizeof out);
+
+    crypton_curve25519_donna(out, sec, base);    /* the shared secret */
+    CT_PUBLIC(out, sizeof out);
+    ct_sink(out, sizeof out);
+    return 0;
+}
diff --git a/cbits/tests/ct/run.sh b/cbits/tests/ct/run.sh
new file mode 100644
--- /dev/null
+++ b/cbits/tests/ct/run.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+# Does the code that handles a secret run in time independent of it?
+#
+# memcheck already follows undefined bytes through arithmetic and reports the
+# moment one decides a branch or an address.  That is the same question, so
+# each driver declares its secret undefined and runs under valgrind: every
+# report names a place where the secret reached a branch or an index.
+# The technique is Adam Langley's ctgrind.
+#
+# Without valgrind the drivers are still built and run, which says only that
+# the plumbing is right -- it checks nothing about timing, and says so.
+#
+# Usage: cbits/tests/ct/run.sh [build-dir]
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
+out=${1:-$(mktemp -d)}
+cc=${CC:-cc}
+mkdir -p "$out"
+cd "$root"
+
+D=cbits/decaf
+decaf_src="$D/ed448goldilocks/decaf_all.c $D/ed448goldilocks/eddsa.c
+           $D/ed448goldilocks/scalar.c $D/p448/f_arithmetic.c
+           $D/p448/f_generic.c $D/utils.c $D/p448/arch_ref64/f_impl.c
+           cbits/crypton_sha3.c"
+decaf_inc="-DCRYPTON_DECAF_WORD_BITS=64 -I$D/include -I$D/p448
+           -I$D/include/arch_ref64 -I$D/p448/arch_ref64"
+
+# The generic C, not whatever the machine happens to offer.  A build that
+# takes AES-NI reports nothing from the AES driver and says nothing about the
+# table-driven code every other machine runs.
+aes_src="cbits/crypton_aes.c cbits/aes/generic.c cbits/aes/gf.c"
+
+status=0
+have_valgrind=no
+ct_define=
+if command -v valgrind > /dev/null 2>&1; then
+	have_valgrind=yes
+	ct_define=-DCRYPTON_CT_VALGRIND
+fi
+
+run_one() {
+	name=$1; srcs=$2; inc=$3
+	# shellcheck disable=SC2086
+	$cc -O2 -g $ct_define -Icbits -Icbits/include64 $inc \
+		-o "$out/$name" "cbits/tests/ct/ct_$name.c" $srcs 2> "$out/$name.cc" || {
+		echo "FAIL $name did not build"; sed -n '1,12p' "$out/$name.cc"; status=1; return
+	}
+	if [ "$have_valgrind" = no ]; then
+		"$out/$name" > /dev/null 2>&1 && echo "built $name (no valgrind here; nothing checked)" \
+			|| { echo "FAIL $name did not run"; status=1; }
+		return
+	fi
+	valgrind --error-exitcode=0 --track-origins=yes --num-callers=20 \
+		--log-file="$out/$name.log" "$out/$name" > /dev/null 2>&1 || true
+	n=$(grep -c "^==[0-9]*== \(Conditional jump\|Use of uninitialised\)" "$out/$name.log" || true)
+	# Which places did it name?  Only the frame the report is against -- the
+	# "at" line -- is the place; the "by" lines below it are how the code got
+	# there and are not themselves branching on anything.  A site is
+	# "file:line", and the ones listed in known.txt are understood.
+	sites=$(sed -n 's/^==[0-9]*==    at 0x[0-9A-Fa-f]*: [A-Za-z_0-9]* (\([^)]*\))$/\1/p' \
+		"$out/$name.log" | grep -v '^ct_' | sort -u)
+	unknown=
+	for site in $sites; do
+		file=${site%%:*}
+		if grep -q "^$site[[:space:]]" cbits/tests/ct/known.txt ||
+		   grep -q "^$file[[:space:]]" cbits/tests/ct/known.txt; then
+			continue
+		fi
+		unknown="$unknown $site"
+	done
+
+	case $name in
+	canary)
+		# the calibration: silence here would mean the marking never reached
+		# the code, and every other zero in this run would be worthless
+		if [ "$n" -eq 0 ]; then
+			echo "FAIL canary: the deliberately leaky driver reported nothing,"
+			echo "     so the marking is not reaching the code and nothing below counts"
+			status=1
+		else
+			echo "ok   canary: reported $n, so the marking works"
+		fi
+		;;
+	aes)
+		# Silence would mean the build took an accelerated path and so
+		# measured nothing; the tables reporting is the point.
+		if [ "$n" -eq 0 ]; then
+			echo "FAIL aes: reported nothing, so this build did not take the"
+			echo "     table-driven code the driver exists to measure"
+			status=1
+		else
+			echo "note aes: $n report(s), from $(echo "$sites" | tr '\n' ' ')"
+		fi
+		;;
+	*)
+		if [ "$n" -eq 0 ]; then
+			echo "ok   $name: the secret decided nothing"
+		elif [ -z "$unknown" ]; then
+			echo "ok   $name: $n report(s), all known -- $(echo "$sites" | tr '\n' ' ')"
+		else
+			echo "REPORT $name: the secret decided a branch or an address"
+			echo "       somewhere not listed in cbits/tests/ct/known.txt:"
+			for site in $unknown; do echo "         $site"; done
+			sed -n '/Conditional jump\|Use of uninitialised/,/^==[0-9]*== $/p' \
+				"$out/$name.log" | head -30 | sed 's/^/    /'
+			status=1
+		fi
+		;;
+	esac
+}
+
+# The calibration first: it must report, or nothing below means anything.
+run_one canary  "" ""
+
+run_one powm    "cbits/crypton_powm.c" ""
+run_one p256    "cbits/p256/p256.c cbits/p256/p256_ec.c" ""
+run_one x25519  "cbits/curve25519/curve25519-donna-c64.c" ""
+run_one ed25519 "cbits/ed25519/ed25519.c cbits/crypton_sha512.c" "-Icbits/ed25519"
+run_one decaf   "$decaf_src" "$decaf_inc"
+run_one chapoly "cbits/crypton_chacha.c cbits/crypton_poly1305.c" ""
+run_one aes     "$aes_src" ""
+
+if [ "$have_valgrind" = no ]; then
+	echo "skip no valgrind here, so none of the above was checked"
+	exit 0
+fi
+exit $status
diff --git a/cbits/tests/endian/README b/cbits/tests/endian/README
new file mode 100644
--- /dev/null
+++ b/cbits/tests/endian/README
@@ -0,0 +1,27 @@
+Does this C give the same answers on a big-endian machine?
+
+The cabal file lists s390x and ppc64 among the architectures it builds for.
+Neither is in the CI matrix, and neither had ever compiled this code, let
+alone run it.  Eighteen files read their input through the loaders in
+crypton_align.h -- which were rewritten from word-typed casts to memcpy in
+#256 -- and eight more decide something from the byte order themselves.  That
+is the largest body of untested endianness-sensitive code in the tree, and the
+riskiest part of it is the most recently written.
+
+The two sides cannot be compared in one run the way the 32-bit harness
+compares two builds, because only one endianness exists on the machine doing
+the comparing.  So the answers are frozen instead: vectors.txt is what this
+code gives on a little-endian host, and check mode reads it back and compares.
+Any machine can run check mode, and a big-endian one that disagrees says so
+line by line.
+
+  cbits/tests/endian/run.sh generate   write vectors.txt from this machine
+  cbits/tests/endian/run.sh            check this machine against vectors.txt
+
+Generate mode is for a maintainer on a little-endian machine after adding a
+primitive, and the file it writes is committed.  It is not run in CI, where
+only check mode makes sense.
+
+The first few lines of vectors.txt are published test vectors rather than
+whatever this code happened to produce -- SHA-256 of "abc" and the like --
+so that a mistake on the generating host is caught rather than frozen in.
diff --git a/cbits/tests/endian/endian.c b/cbits/tests/endian/endian.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/endian/endian.c
@@ -0,0 +1,192 @@
+/* What this C answers, so that a big-endian machine can be asked the same.
+ *
+ * Every primitive here reads its input a word at a time, or writes its output
+ * that way, or both -- which is the step that goes wrong when the byte order
+ * changes.  Each one is fed the same deterministic bytes at several lengths,
+ * including lengths either side of its block, since the tail is where the
+ * length is packed in and where the byte order shows.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "crypton_md4.h"
+#include "crypton_md5.h"
+#include "crypton_sha1.h"
+#include "crypton_sha256.h"
+#include "crypton_sha512.h"
+#include "crypton_sha3.h"
+#include "crypton_ripemd.h"
+#include "crypton_skein256.h"
+#include "crypton_skein512.h"
+#include "crypton_tiger.h"
+#include "crypton_whirlpool.h"
+#include "crypton_chacha.h"
+#include "crypton_salsa.h"
+#include "crypton_poly1305.h"
+
+/* The skein headers spell the prefix "cryponite", which nothing defines. */
+void crypton_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
+void crypton_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len);
+void crypton_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out);
+void crypton_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
+void crypton_skein512_update(struct skein512_ctx *ctx, const uint8_t *data, uint32_t len);
+void crypton_skein512_finalize(struct skein512_ctx *ctx, uint32_t hashlen, uint8_t *out);
+
+static int generating;
+static FILE *vf;
+static int failures, checked;
+
+/* one answer: named, and either written out or compared with what was */
+static void answer(const char *name, const uint8_t *out, size_t n) {
+    char got[512], want[512], label[128];
+    size_t i;
+    for (i = 0; i < n && i * 2 + 2 < sizeof got; i++)
+        snprintf(got + i * 2, 3, "%02x", out[i]);
+    got[n * 2] = 0;
+    /* an answer of no bytes still has to be a token, or the reader below
+       takes the next line's name for this line's answer and everything
+       after it is compared against the wrong thing */
+    if (n == 0) strcpy(got, "-");
+    if (generating) {
+        fprintf(vf, "%s %s\n", name, got);
+        return;
+    }
+    if (fscanf(vf, "%127s %511s", label, want) != 2) {
+        printf("FAIL %s: vectors.txt ended early\n", name);
+        failures++;
+        return;
+    }
+    checked++;
+    if (strcmp(label, name) != 0) {
+        printf("FAIL out of step: expected %s, vectors.txt has %s\n", name, label);
+        failures++;
+    } else if (strcmp(got, want) != 0) {
+        printf("FAIL %s\n  little-endian %s\n  this machine  %s\n", name, want, got);
+        failures++;
+    }
+}
+
+/* the input: deterministic, and at lengths either side of every block size */
+static const size_t lengths[] = {0, 1, 3, 55, 56, 63, 64, 65, 111, 112,
+                                 127, 128, 129, 135, 136, 255, 256, 1000};
+static uint8_t buf[1024];
+static void fill(void) {
+    size_t i;
+    for (i = 0; i < sizeof buf; i++) buf[i] = (uint8_t)(i * 7 + (i >> 5) * 31);
+}
+
+#define HASH(nm, ctxt, initcall, updcall, fincall, outlen)                  \
+    do {                                                                    \
+        size_t li;                                                          \
+        for (li = 0; li < sizeof lengths / sizeof *lengths; li++) {         \
+            ctxt ctx;                                                       \
+            uint8_t out[outlen];                                            \
+            char nmbuf[128];                                                \
+            initcall;                                                       \
+            updcall;                                                        \
+            fincall;                                                        \
+            snprintf(nmbuf, sizeof nmbuf, "%s/%zu", nm, lengths[li]);                      \
+            answer(nmbuf, out, outlen);                                     \
+        }                                                                   \
+    } while (0)
+
+int main(int argc, char **argv) {
+    generating = (argc > 1 && strcmp(argv[1], "generate") == 0);
+    vf = fopen(argc > 2 ? argv[2] : "cbits/tests/endian/vectors.txt",
+               generating ? "w" : "r");
+    if (!vf) { printf("cannot open vectors.txt\n"); return 2; }
+    fill();
+
+    HASH("md4", struct md4_ctx, crypton_md4_init(&ctx),
+         crypton_md4_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_md4_finalize(&ctx, out), 16);
+    HASH("md5", struct md5_ctx, crypton_md5_init(&ctx),
+         crypton_md5_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_md5_finalize(&ctx, out), 16);
+    HASH("sha1", struct sha1_ctx, crypton_sha1_init(&ctx),
+         crypton_sha1_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_sha1_finalize(&ctx, out), 20);
+    HASH("sha256", struct sha256_ctx, crypton_sha256_init(&ctx),
+         crypton_sha256_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_sha256_finalize(&ctx, out), 32);
+    HASH("sha512", struct sha512_ctx, crypton_sha512_init(&ctx),
+         crypton_sha512_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_sha512_finalize(&ctx, out), 64);
+    /* sha3's context ends in a flexible buffer whose width comes from the
+     * hash length, so it is not a plain automatic variable like the rest. */
+    {
+        size_t li;
+        for (li = 0; li < sizeof lengths / sizeof *lengths; li++) {
+            uint8_t space[SHA3_CTX_BUF_MAX_SIZE];
+            struct sha3_ctx *ctx = (struct sha3_ctx *)space;
+            uint8_t out[32];
+            char nmbuf[128];
+            crypton_sha3_init(ctx, 256);
+            crypton_sha3_update(ctx, buf, (uint32_t)lengths[li]);
+            crypton_sha3_finalize(ctx, 256, out);
+            snprintf(nmbuf, sizeof nmbuf, "sha3-256/%zu", lengths[li]);
+            answer(nmbuf, out, sizeof out);
+        }
+    }
+    HASH("ripemd160", struct ripemd160_ctx, crypton_ripemd160_init(&ctx),
+         crypton_ripemd160_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_ripemd160_finalize(&ctx, out), 20);
+    HASH("skein256", struct skein256_ctx, crypton_skein256_init(&ctx, 256),
+         crypton_skein256_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_skein256_finalize(&ctx, 256, out), 32);
+    HASH("skein512", struct skein512_ctx, crypton_skein512_init(&ctx, 512),
+         crypton_skein512_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_skein512_finalize(&ctx, 512, out), 64);
+    HASH("tiger", struct tiger_ctx, crypton_tiger_init(&ctx),
+         crypton_tiger_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_tiger_finalize(&ctx, out), 24);
+    HASH("whirlpool", struct whirlpool_ctx, crypton_whirlpool_init(&ctx),
+         crypton_whirlpool_update(&ctx, buf, (uint32_t)lengths[li]),
+         crypton_whirlpool_finalize(&ctx, out), 64);
+
+    /* The stream ciphers and the one-time authenticator.  Each reads its key
+     * and its input a word at a time and writes its output the same way, so
+     * the byte order shows in the answer rather than in a length field. */
+    {
+        size_t li;
+        for (li = 0; li < sizeof lengths / sizeof *lengths; li++) {
+            crypton_chacha_context cctx;
+            crypton_salsa_context sctx;
+            poly1305_ctx pctx;
+            poly1305_key pkey;
+            poly1305_mac mac;
+            uint8_t key[32], iv[8], outbuf[1024];
+            char nmbuf[128];
+            size_t i;
+
+            for (i = 0; i < sizeof key; i++) key[i] = (uint8_t)(i * 11 + 3);
+            for (i = 0; i < sizeof iv; i++) iv[i] = (uint8_t)(i * 5 + 1);
+
+            crypton_chacha_init(&cctx, 20, sizeof key, key, sizeof iv, iv);
+            crypton_chacha_combine(outbuf, &cctx, buf, (uint32_t)lengths[li]);
+            snprintf(nmbuf, sizeof nmbuf, "chacha20/%zu", lengths[li]);
+            answer(nmbuf, outbuf, lengths[li] < 64 ? lengths[li] : 64);
+
+            crypton_salsa_init(&sctx, 20, sizeof key, key, sizeof iv, iv);
+            crypton_salsa_combine(outbuf, &sctx, buf, (uint32_t)lengths[li]);
+            snprintf(nmbuf, sizeof nmbuf, "salsa20/%zu", lengths[li]);
+            answer(nmbuf, outbuf, lengths[li] < 64 ? lengths[li] : 64);
+
+            for (i = 0; i < sizeof pkey; i++) pkey[i] = (uint8_t)(i * 13 + 7);
+            crypton_poly1305_init(&pctx, &pkey);
+            crypton_poly1305_update(&pctx, buf, (uint32_t)lengths[li]);
+            crypton_poly1305_finalize(mac, &pctx);
+            snprintf(nmbuf, sizeof nmbuf, "poly1305/%zu", lengths[li]);
+            answer(nmbuf, mac, sizeof mac);
+        }
+    }
+
+    if (!generating && failures == 0)
+        printf("ok   %d answers match the little-endian ones\n", checked);
+    else if (!generating)
+        printf("FAIL %d of %d answers differ\n", failures, checked);
+    fclose(vf);
+    return failures != 0;
+}
diff --git a/cbits/tests/endian/run.sh b/cbits/tests/endian/run.sh
new file mode 100644
--- /dev/null
+++ b/cbits/tests/endian/run.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# Does this C give the same answers on a big-endian machine?
+#
+# s390x and ppc64 are among the architectures the cabal file builds for, and
+# neither is in the matrix.  Eighteen files read their input through the
+# loaders in crypton_align.h -- rewritten from word-typed casts to memcpy in
+# #256 -- and eight more decide something from the byte order themselves.
+#
+# The two sides cannot be compared in one run the way the 32-bit harness
+# compares two builds, because the machine doing the comparing has only one
+# byte order.  So the answers are frozen: vectors.txt is what this code gives
+# on a little-endian host, and check mode reads it back.
+#
+# Usage: cbits/tests/endian/run.sh [generate] [build-dir]
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
+mode=check
+if [ "${1:-}" = generate ]; then mode=generate; shift; fi
+out=${1:-$(mktemp -d)}
+cc=${CC:-cc}
+mkdir -p "$out"
+cd "$root"
+
+srcs="cbits/crypton_md4.c cbits/crypton_md5.c cbits/crypton_sha1.c
+      cbits/crypton_sha256.c cbits/crypton_sha512.c cbits/crypton_sha3.c
+      cbits/crypton_ripemd.c cbits/crypton_skein256.c cbits/crypton_skein512.c
+      cbits/crypton_tiger.c cbits/crypton_whirlpool.c
+      cbits/crypton_chacha.c cbits/crypton_salsa.c cbits/crypton_poly1305.c"
+
+# Generating is done under the sanitizers, since a driver that writes out of
+# bounds would otherwise freeze whatever it happened to leave behind.  That
+# is not hypothetical: sha3's context ends in a flexible buffer and the first
+# draft of the driver put it on the stack as a plain struct.
+san=
+if [ "$mode" = generate ]; then
+	san="-fsanitize=address,undefined -fno-sanitize-recover=all"
+fi
+
+# shellcheck disable=SC2086
+$cc -O2 -g $san -Icbits -Icbits/include64 -o "$out/endian" \
+	cbits/tests/endian/endian.c $srcs
+
+if [ "$mode" = generate ]; then
+	"$out/endian" generate cbits/tests/endian/vectors.txt
+	echo "wrote $(wc -l < cbits/tests/endian/vectors.txt | tr -d ' ') answers"
+	echo "commit cbits/tests/endian/vectors.txt"
+else
+	"$out/endian" check cbits/tests/endian/vectors.txt
+fi
diff --git a/cbits/tests/endian/vectors.txt b/cbits/tests/endian/vectors.txt
new file mode 100644
--- /dev/null
+++ b/cbits/tests/endian/vectors.txt
@@ -0,0 +1,252 @@
+md4/0 31d6cfe0d16ae931b73c59d7e0c089c0
+md4/1 47c61a0fa8738ba77308a8a600f88e4b
+md4/3 5dc60555aff84f4f4d75c487477bd40e
+md4/55 7fb3b8a921fbb273575603f44876e276
+md4/56 150c4579f2a8f07aa321b3825b46cbf3
+md4/63 a6fc40dc3217aaf3bdd437886ee24644
+md4/64 e29ccc2f2131c0d40572b6dbf243369b
+md4/65 9e8345b86c1dc8ed95f1a591bd01a02a
+md4/111 815d46faeafcc449d668b476b28d16b4
+md4/112 bb70170948d31fae99063ea7ce0be725
+md4/127 c6f47dc12fd474f894fa9f51e043a109
+md4/128 1379e209df9100a5b5c0d3c3068baf23
+md4/129 bf3a7c34766fa54bfa6335e8fd2d89b5
+md4/135 0985ede04e702bd38e6c10955120c3dc
+md4/136 46e572e144b3130b4993660116ed1d29
+md4/255 adc67d84a7b2ccfe7e5d541a4c55aaae
+md4/256 1ef108f24aac5e2df49d8e692a68cfae
+md4/1000 0ae32726214fc6eb8133de6ec0e3ab03
+md5/0 d41d8cd98f00b204e9800998ecf8427e
+md5/1 93b885adfe0da089cdf634904fd59f71
+md5/3 ed41c1aca5ad5feb033df37822dae4b7
+md5/55 c051c9637f919672c309560032dee7ab
+md5/56 0f4e8d49afd96d05c011692366b0e92f
+md5/63 39b5ef10a4f0648885ac75ec5fbfbd9e
+md5/64 56bce76bade2e3259fd44ec9592893f3
+md5/65 a41bf4e0f25f0705ead601e8f5481dd1
+md5/111 39ffc0fb12a340f0f0cef28c7c5d73f2
+md5/112 9330636dc725a2bea4026e2ffcbf5e01
+md5/127 bb7911f7538cf8139325caf596135fa0
+md5/128 89248d055d67dc618b5fa8e6a7936747
+md5/129 e0295e53676fb80f77c499a6f747705d
+md5/135 80c0d9601f6b0371c533d601deac9d15
+md5/136 5d49aa8ae1bb7f6d426897800b281547
+md5/255 38c3929ff959900de1f79decd32110ee
+md5/256 def8272a2a5a237a4590c8abc83261c5
+md5/1000 6d1e3c683bc932d465a43307a4dfb791
+sha1/0 da39a3ee5e6b4b0d3255bfef95601890afd80709
+sha1/1 5ba93c9db0cff93f52b521d7420e43f6eda2784f
+sha1/3 75550941124b46eb4161d17ac200c05c4fc03ce7
+sha1/55 4574696c8a057e3b8169f6946e96fe694ac1f63d
+sha1/56 cc1ecce36813cd3f62aa8b6b00b9ca127619fc41
+sha1/63 fa09a13f3c17facdcf2fe69a63023e5b5bdb7ab4
+sha1/64 cb8d5827b951666a2fd890cea3fc5afbe527b6da
+sha1/65 7264c8d694493c5f81fb537c6085387878aa1571
+sha1/111 50d721885aca3ebeeaaec214d7bed12303fdbbb9
+sha1/112 ecace0ac5661c929fbad2810d081988461f9375d
+sha1/127 9039e73e76720f39656f5b10aa188d9135a0dd4e
+sha1/128 cfb672f8266b134afdbc79b79988d9a2aa2c511f
+sha1/129 f9ccb7eb40a100fa075f0f1992e61bc775d8c882
+sha1/135 9cec88751569f9d70ef6bb764fac3a2f2ec93a51
+sha1/136 2125c7780f72d171f651cdb70efa0f5011a45c1d
+sha1/255 c9069eb027c7b6de5d2385779003c0c3b81152f4
+sha1/256 d397a655930755132ebc094b6353b23dfee0f155
+sha1/1000 7f0b25e59adefabd5323e7fba76def0018847494
+sha256/0 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+sha256/1 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d
+sha256/3 b361d0f9a938a2bb4fbdc9c21dc5a859788041b0040919d8a811c1888184f4df
+sha256/55 8c9d785249c00ba19b5c8c6d0df51b3da614b8af732fe566909d47897f580f79
+sha256/56 e458987ff5bc3a0e1d2d84fb1cab06a8d8e7bcec2d5b6fe43498280b93d65003
+sha256/63 e3c8148d3ba2928b012cc55b325faa2d2bec48d319fed4ea2a3791150ebbfb60
+sha256/64 e9c6e41c26bd6bedc6a8e61bc7a02b85818c632875643db2c5c5db65eac2d0b8
+sha256/65 f0960adca320b44bc378b2839ad6b0dbfd2d7d98fb12802f7fb823ab9c424f93
+sha256/111 ecf5dd1da8d2b562cbdb69e6714ad568483f1b0a5b79c65e07d4b1807190fc90
+sha256/112 51221cdabbf22da7d38a3ec00200cd011bab7487bdf6947bb3356bc0c94bdea8
+sha256/127 75df9f55cf2ec2201b5bdb9671df418dfd6b7fdcff8dd85b768872949ef0863c
+sha256/128 fa52030abda28172c20bc098a70e13e4a764979b7f536a332f6ea29867c0dcb3
+sha256/129 e08048e99eb6c53cb09d709071f1f1eda4d52cbfbff9dd4e756ce4c939a50498
+sha256/135 4cf50d0a4148ed5147501e6ef09835c775da2ac903e0760288bdfa03454fa923
+sha256/136 a571b968a9479df4ddb5bedcaa1cde191864b5fee12d969407056eeb2a39aeb0
+sha256/255 eb6337ccc19a34a3ac4fb140185955cfaaab38440deb2ff87ed6f22ff1fa0239
+sha256/256 0617cb171a31c804506afbbec540a7a1d17953017a883fc7ff2bc913d77bf2e7
+sha256/1000 7fd5abf2b68d694aa89ca16c6a325450c83ad0b07cdbe3c86dbd55db684623b6
+sha512/0 cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+sha512/1 b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee
+sha512/3 9d1d055e0ac16db8b8b3b6c44692743b855129eb6b9fb9706ac623cf5c086ce4983ae494e5abeafc77a05e5e95f87c96bf8bd9434bccace808732165a43a6412
+sha512/55 541042668dfe41adb3801f723e7c02886e5f1b4fda826bfe4d2ae2a2749ad9f2a764509f74018e8b050c6e822283546066fa6aa09389a50d4b66c0890ad146cd
+sha512/56 a09c32a7c3a410c136ef656933a616366394455b85ec7ad284f1048d7472d68cea43de3df7f24b384ebcd724ee552325dfef830619022a189ef2c36fa702693c
+sha512/63 4d6719f704edfd162acd129079a6692dfcbd99497394aa8703667288e3fca6bc1bc45f95616458ae43b7529ffd08d7b06aa5b5a8193051aeaec23cedc444dc96
+sha512/64 dce432552c3db0b0628a924dd1fb617d7ccff63dd7643aaba7f0d97629c6c22cb8e9f24eea742b4aaa5b72f4772ca387a1175ef2bc3f6d2653b3a9479ef35fa5
+sha512/65 0c627ddbf62632ac97c3b955db49181fec702992f0a0bd07b553f226075133db40532c90854b1447675ced18f950fa2a2207d6b6db1757b34374e0f5f3900a3b
+sha512/111 993f2d3b273771809640eb7cd2f2830681faaec2d2ea91375b6467b5b04b0581e02262d9715201c7b5c1abcb3f5a9f64d4f2e8f18961a25153d3b6c99a81f501
+sha512/112 186430ceef81d4724e1196c32a956fff9c11676064711432f9b828001c488cd3beaf8f35c3283887bbdbed1915c5dce0b298d9c88ccf8113ad5e1f0f6121993c
+sha512/127 1dae2ca13d511448d2fda00b57f03481a3c01a51273c756f6dd4934a2c271f0096960b3188a2cf1c485327958785abdfcc876e17ad4f16a66d311a81270a8b40
+sha512/128 dfe931ea5f331a50c1f2e2b8ef5e9d417bac976f13c1439a1655a134669a64d4f9c33ad540233a43796ea6266eae953a6b99d49fd88f27d4f342c0fe43ae42ca
+sha512/129 eca5ea3ff8033c59d5a891c5d0e2cfb099d4cab8bcea7f4878342fa60a10f26cb3e570870932c69b6b3419e865f9dd4e0281a132861c54ea21947d3bbd599aa1
+sha512/135 000bb1bda38edd5e935b1f4a865ff74cacc325af1c8485ddd04a0f4e3f859ac5c1733f32af5c6646cb94dbb4678d8704d022fbfcea8f2dbcbc41e5cdc5921fed
+sha512/136 0b0ce141f1a6a6d27522b26a2683aac47b04e99d64e29472969391fe5521dd0d7e6898c84b007103ee908dc73f7acb7cb1c4a4d4b418aaa3edba51cdd9e3de60
+sha512/255 45bf80a489f2579063e0890396d5bcbea66469e93ccf0e04cf933e7b10e7e9826ec0376d706b0f601599f69dc8629a1bdb4de1c9b03890ea0ac7889db258ffef
+sha512/256 8e287890cf2beb5414ff4035dc579fc41b8d9ef21febb0a40e3d7c310f291ed3c2588a637bd314ea3b73ac398d0183a0dca8e4cc830cc59f39b9567427766bba
+sha512/1000 8f61fbcd0e1f611d5f996c4c21002f9311ca0e4f4a101fd9843596a5693230e40e6f3fbe59bbdfd5ece955563234939d2a1ec809f6572ac06119f82a5c1a90e1
+sha3-256/0 a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
+sha3-256/1 5d53469f20fef4f8eab52b88044ede69c77a6a68a60728609fc4a65ff531e7d0
+sha3-256/3 aa6c85d1a41110dd488f4a35719cf4bbcf2634d7c50401958ad41097096c7760
+sha3-256/55 81fe59ad864db751440e1251d7792a74d1af93ff48e24b25b65639f97bf48bf2
+sha3-256/56 129a430d7d7f2ad866b0da79f1c50a8a0f80f248c21a280eb3528cdff3b6f26c
+sha3-256/63 d305b528e64c7e3c88cc1a937c152c169ad07871cb359e71f478ca6c1ad20c7e
+sha3-256/64 c47f2570ff2e79c00bcbd0674a2ee9e0eed07c0c5db8c3a1aa68357aa39abe97
+sha3-256/65 5b73115520ad1b600cae25ebdbd2510037ea11e158c7ec8d2b63b9945b32981a
+sha3-256/111 2aa0850d3ed0fa9d5e8f00053f0f4f8248dc24577925d27c82e7584a49da39a9
+sha3-256/112 c031eec2ab94c67081f5729f8718dc048d3a17daed923fc6d247f495ca66acf7
+sha3-256/127 92927f72784017dfc937c60ced80e2bba7c59abe9367e8bbf95b76afd9123d04
+sha3-256/128 10cab47e12f96037ac9d1d962a2031fd9e3bdf345cb5ae4827ae19ab1c50d077
+sha3-256/129 fb32880265355aa1082038604b8b633933f16c650dd402546e5f92db425a6663
+sha3-256/135 009f270e8f6dcaa6a7af6134429c49068a372ae93ed022bfd39eb665b3b226ee
+sha3-256/136 efde869e19bad5db360fe59a0ea91abe35ea8e0fc87aadcef11d480cb63d1d7e
+sha3-256/255 1998ee5adc07d9b0f3c87bb2520dac580b48cb1e65ee14959634f4e25e78618e
+sha3-256/256 71d78d32c485425571f393927366001e60ea0d404be34137b9bfad1c065293d0
+sha3-256/1000 671cf26630a648c48c2eee1125dbcdc3f0b0ee7ea5fa5e4311efe7b536db03ea
+ripemd160/0 9c1185a5c5e9fc54612808977ee8f548b2258d31
+ripemd160/1 c81b94933420221a7ac004a90242d8b1d3e5070d
+ripemd160/3 1a51cd060324236aef3ca82f633638c3d34693f7
+ripemd160/55 79dd03427a79bff167b170be1fd01edaa69c48da
+ripemd160/56 8fd66d9a2808b45155c2532c5be09a49db1138b7
+ripemd160/63 9fed7522e7537e1ec07d1d3fb04fe528b94db59d
+ripemd160/64 bb8e58b9b697f8a6001318e6dd7b97fdb96cbbb2
+ripemd160/65 9f4b683e9ffcef970435986daab885750258af82
+ripemd160/111 c46b3c4192a0b9db5b6f327dca3d2979536a51b8
+ripemd160/112 4146822be4f0fb524965b46e18b405400e4a077e
+ripemd160/127 f000414f29cfd8c047cc4e00594ba4448baae0a1
+ripemd160/128 2864a0a1a3f701a27dd29eb3b08e6eb98705e6da
+ripemd160/129 5d12f9405bf021ac7edd672d9b05f0be6c40b5c3
+ripemd160/135 87667a9b70214ed9552e049c9e173f774e7045a6
+ripemd160/136 34e83a91054cac23d5bee365e346bd9592e3ad80
+ripemd160/255 fd4fa53a24ed05cac5746fe7ad4a51aa7b0f906f
+ripemd160/256 4d29394d45cb3a350fb04abfd7abefd98d5dbc71
+ripemd160/1000 09d36b8fc9c87979223ad021c0e5bed386f1c502
+skein256/0 c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba
+skein256/1 34e2b65bf0be667ca5deba82c37cb253eb9f8474f3426ba622a25219fd182433
+skein256/3 175623dce1b0cb69bed8a38af2ec2d8f81e2ca1edac0423bc765b90a89eb693f
+skein256/55 acb6ea7280880ee8814bf2228fba49c9860bea7bcdd18f5fa9c93471d3af4585
+skein256/56 87edff7a077c3a72ff2ad09dad290dcb156aaacf472d11451231cfb48577960d
+skein256/63 3a74537a726a4987042e8cf3c285396b94cdca3297f3c618af0035efd2d77cd0
+skein256/64 31e6401745b92aa5cabbb55a032b9285e9a978fd7ee0a7756903190bf31dffc2
+skein256/65 ec66f99651b0d7d4cfead397b4d3d2284fe0d3cde3df2fc00f7faea0d5e83eb0
+skein256/111 a67fc7fbb5babe99f92ccd808bf61af941a69ea064b01c145ab8b8a51c65dc83
+skein256/112 c738917c7e782f30c1bb7af09e9593f5e12ba339353f10a12c83d9054bd81c53
+skein256/127 c3ba1dfa5b9dd1e80a203026213e34b5408663a895f91a09e719f9dcb187f7b4
+skein256/128 81188e87abc45684a64ca1591259830f758a5c8b11a7144a0c58fbab6923bd7e
+skein256/129 f6c477673becfbbbdc6b6510649f94423b91d5b159181d8cdb4d60d5aadb9c9e
+skein256/135 b5c7ba0a7265390af1982e3c61d15d30cf6f25b6c0452d6bbb932de85cf8d1fc
+skein256/136 e982d50fc214234541c6b1779bacf6c6d592d6c88275635f3fe9f4517c04a3e9
+skein256/255 e9a0544f7252e46be8e3dedf5a9db4f502f01183a6c593cf25e7fad93ac5e888
+skein256/256 625327ea0bc0edcb43b70f0b979742cf223f55ae15bf021f3636d50141b23853
+skein256/1000 23b8bbd0a122b07e9ccf552a0763e7aaead3ef25b74cea8282ea0c0fd24de7b9
+skein512/0 bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a
+skein512/1 40285f433699a1d8c799b276ccf18010c9dc9d418b0e8a4ed987b44c61c01c5ccbcc0977b1d34a4d3665d20e12716df934d208fea6607f74968ed86be3c99832
+skein512/3 cf8bc9d2f25e5a8633d564fd73ffc76308819232a13a1dece60ce8e81651e5bd7569c95cb4b5772c1cfa885acadfdbab5bb94b28b01421770f278b1d8968c053
+skein512/55 523aecc435dcb541f5be26dd5935132b1f40bc78abd8aaa2b87f29202837e3b55ad576ffeb1692a47b6e0c5a2bb0fb669262751900dcf5c63dd654043ed934a7
+skein512/56 81641af4c81d0f52f0345c1e742a8c52a28fc09b22ad132c5599fb50c77f5c4f310d3a213fe7a1768711df13361a60c67e0ab6587592b30aa01433a79b134260
+skein512/63 5aa0c9c865d56c0dc8e6430290d3e3d6c785912c1ec2961dc4a928efefe4faa4711ae95b976db1b3d1af33cb4992dd84e35ce204371d357fc03754f9eb3dc25b
+skein512/64 2ebf29904f1d770a56fa50408927dc948bb28bed094aa735940653b204b2e23adb18932893cb4f927be7d0b86eed144f7cbccb02afacb47c834b4fdcafce5dac
+skein512/65 debfe997c41e391d00143289d49c807b1b763569b29b013ff58b015172859eaa202b223f17c357506765c2ec43f561c339d7b184b1982c1d44a3c4b3933f8d62
+skein512/111 f338e3b93dea8713b80f3d4f61f7cea1bb6b3c71ba90b0798e5178ba0c6431c68e34c6a6759c0c1181ab5ca765c17d3a200b4a440c262b92e2158b87a5576908
+skein512/112 4d6372e5f65a3462730a9db06eda6b6e2b35672abbc624cba58ec17440bd0d922a25d5923685d4625ca955c88da134353df92638d5cd3c3f9f1500138c639191
+skein512/127 c9094df9b9e0bfdb94a36b291fa26150a7d0ab2d5c90e9364c58ee1144eee6c8939333ed796af9ee0f84286f46748002cca1a9c9a6f84f3d3a71fa6562afece1
+skein512/128 9a69ca7d3222bb63d0ffa9b153ec118356e8c18b59adfb23376836b2d9f1a4684117000594261c91fbfef549f188cf831bbd27142b5af4df8be1f80ca0490d9b
+skein512/129 cbef633515a50c561518d1a7a200de7cb269ea17a2861a852d65002562174a5b471adbd0e45ab4317827b2756f2be2b897da906456a062927d9e14839eae7ede
+skein512/135 116b23ac95a0b499a62e571703f43af7e79c8de5450bc793964cdd1c64158eaa7ec463ce67ab1b3fd23c5b653ffa09015efbc225f753c0a5964687a16c25fe30
+skein512/136 12bc711a66f7f09f7ad2994e666c7064c3c9a1695a8fe6bc0092cf035e11192aab53c006e409449f0971fd68f4248253477d099ba2d85a4ada064bbe91c53558
+skein512/255 dd7f2f871bcdd425b07c691325b808aca79551e661dc9a72b95d5f059ae0c1e7039f64d10bea14b4c2fc251e5a7ce11b4e9400503fd7e3684d4eefcf2ceca425
+skein512/256 234270864103c6fed1dc8249bf6c91f5660f5438a6cec17c8f97dfbcde0e4a9ffc3a971f4e23d58db01fab96621a13f41ca4914883f7a149401a3d347161532c
+skein512/1000 3631c9fcf9af7bd2c9e6b474bf56de55261f002c5a2d0ecb478a6024a56366efba38e4b6936d3a5cdc8f7800dc39250520dded0b3583719c2b3159a9ea326b25
+tiger/0 3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3
+tiger/1 5d9ed00a030e638bdb753a6a24fb900e5a63b8e73e6c25b6
+tiger/3 53b5b6bd6bab3c1c63a8d8c62572e9a3502eae8e80d2143d
+tiger/55 3aa4132b6dce81714c8b76a2b69eb25a870ca99101196d4b
+tiger/56 28a5e8fd6f9b87ec0b9d2e46a94c9663dbe7d81eefb3fe48
+tiger/63 f919691beddf54789d147663465b2ec8f93d7c3999504aa1
+tiger/64 ff2896adeb7883a369da8e71ffa30c6ae0892bd7e4f3b943
+tiger/65 7d72e2840ba3895c4bfc9120daf8858f48741fb5dc64e4ce
+tiger/111 e30fec5c5b5e862b7b085fa7f71c3e6d687fac374149beb7
+tiger/112 0e8f76b3168b6ce849055b405685334c75c6e10fa0ee3727
+tiger/127 01287abaaa42f9150c6fa88dc921fb061a564b6371f67dba
+tiger/128 4a4c0ee2b099109011e95568165ab9216fd2987c0f852a38
+tiger/129 628843804c1769616bc717659fdcf6d21a73f0e6a0ea1eca
+tiger/135 ad945cec97c5ec4565d2f5ebe5d28c297cadc3f90b072526
+tiger/136 322c7537dac6383fe8b55d4fcdd4888574601cd5123b511f
+tiger/255 2bdd7d685a587f31bf202cfd2e1d90e5d53d043b66e773f2
+tiger/256 d8adfc2e0f57a67f8088edb54e2b1f8a93783ffc5aa17833
+tiger/1000 79b772b89f0536af5cf5f34b26ce13ced821d05b468dcdce
+whirlpool/0 19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3
+whirlpool/1 4d9444c212955963d425a410176fccfb74161e6839692b4c11fde2ed6eb559efe0560c39a7b61d5a8bcabd6817a3135af80f342a4942ccaae745abddfb6afed0
+whirlpool/3 a83205596a19327369464c5a98896a274ebea82da9ff93e69ddde9eb7ee90757a2173fd3bf10f6d2b7c241acd0ac23f5f1b414b51d33b26f75e63831f303324f
+whirlpool/55 ad06ca5facbc8457391c279446818876cc2302eaddd9d39576aa39dff825fa9d0fe455bb245c260b7b7672193607cefbefb41a18706fd2fac2a7e1a2fb8f0cfa
+whirlpool/56 6b9e3c1a6714ba482d06f5da0f11c85bb7436f7aebc334e3aeb36745b4cb5d561b27fab0bd59979ede3cca617610c9dccbd0a41b1779e2875ca75761c68e43c0
+whirlpool/63 67da72d6fa8713cba84cca7be5ac53f8ab9d3551a934c7f3376ecebd468d944359772aa83005d815ff74bc26dfe6f22ebbb299b13fbe8f899961d471c76ce871
+whirlpool/64 d893e82c6bf61b2423e8c09e0308d7776b1b1d9556b629cac8c4b82508d6b11891cd2a31312b5d01b640a70acbf94c44c546cdb17389b006943bce62a1e9bd83
+whirlpool/65 6d4593ad291898521736fc63d758a5d5789d9fa3b521cd188f191cd5899b14669006d1d8e6611baa5f782e65aa3d46c47b734b6feca0041a3ada84741e4a57e8
+whirlpool/111 87c6b4fc91580b9ad15689f0e7a9c5378b13646ede124af2cb3cb8124a74e64946214720669f0e2fbd1f23b62980f8d3f19ecda1d26723f7a12f4bef2c6082c4
+whirlpool/112 94826949d4fda3d38d1627bc667261460c8b46e7a11fd24de6116643059e6e02d8271af809e4a4535fd4de8af11c13efad4cea8afe1c348deb10b7c362fd5f23
+whirlpool/127 008f8b8b3dffba832750f542b2a6a3f8ff81547d48715851116c20e475f93893fc7e4ed7a2feaf7595e26b30fde6805335a326b70591ca6d913b66961ea8c5a5
+whirlpool/128 c6dc5ef8e9f449b75b35875c043def87c37ff7f8078044f6cd020fcd311fa5655ba433ef9fd4b6007a0f310f88f63aaba0649175ceb851b0537856c1adf43fa6
+whirlpool/129 2f53c6ddab30118a451bd8dee8e12ee7443e8f3a4132453cc5d74948c008048b5b99ce51f2795e158d0758ccaa6db80f6f1d876533336f7d41f7a098512eb2ca
+whirlpool/135 5835a5cfd59d0f75b0af7ee2b667adcf66168dd6d3f710d895211802e8798fa80a6bcaf05f63473245227332d3983fd6580bc90afd56caebe7470ed95c37b081
+whirlpool/136 0356408b498a01e39ea4966dffc809df366747b79fce4c978bd4cc59c7d6765910b88cfea9ac63b1fc1720bee5c45efb51b22cf7047203f0840076d3c2eb2b24
+whirlpool/255 23a0a3cea1f2d971c467993b40582618a8b75acbb6c3bd7fd76e93ae8d0cd8a6797838daffb13cb21ebb07f8ed3729c77abf83ad4c17c2a5866b46bfd327e1f6
+whirlpool/256 e13d036a12baf02ddcb79354e0e4b6e808eed3102864591d57250fbdfc7822208771af0d0a99b65d355c1c05cd09f57874c14bf1731ecaa24350596d1db0b7ad
+whirlpool/1000 10d2452c3f4d5c4e124cc6e4542c258d7c122da116650fdd894a599df8bd9673b801301794560c2d2b186d131e46a0e4ddf765590b33a1638351727fa9104f27
+chacha20/0 -
+salsa20/0 -
+poly1305/0 d7e4f1fe0b1825323f4c596673808d9a
+chacha20/1 06
+salsa20/1 9e
+poly1305/1 e1eb05201a506d8741b8d5ef79203e58
+chacha20/3 064429
+salsa20/3 9ee7f7
+poly1305/3 453fee0552873db241b6aa62a2c52813
+chacha20/55 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dd
+salsa20/55 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b
+poly1305/55 269c983cc75a974291409f4ae5d403cc
+chacha20/56 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc
+salsa20/56 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b02
+poly1305/56 02b5d7816f3c5bb108e08629f814cce3
+chacha20/63 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bc
+salsa20/63 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae
+poly1305/63 9f0dcc8932e4f6637ee198bf2c8000d6
+chacha20/64 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/64 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/64 6da04a74098654ca6392a1c62040b4cf
+chacha20/65 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/65 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/65 db28069b3ca255821238da8b086fe27a
+chacha20/111 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/111 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/111 f10eb1e2364e6ed3ccc9326d9e56ed64
+chacha20/112 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/112 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/112 183852995a777f1af0f29760c17fa63a
+chacha20/127 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/127 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/127 234fcf18eb82f1b2821f113a22fab7f9
+chacha20/128 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/128 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/128 3f8f2a778d4f490bb17809b1dcdf50e5
+chacha20/129 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/129 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/129 e3fe11911fea16b2b3bf2be93d22c7d7
+chacha20/135 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/135 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/135 4520d5997340683ccd21a2804631d700
+chacha20/136 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/136 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/136 848568032e1e248045e53031e8219393
+chacha20/255 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/255 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/255 8ae46792e840f083d98f7e78f34a8f9d
+chacha20/256 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/256 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/256 427f7cd821633cc0993956cf3a7cf26c
+chacha20/1000 064429ccbd6ef85054af07f8dee3a283e75e844df9a59b1b76addd7d41fb554946f5dd12b49b97f4a72f05b0b41c557e8c69da034ae9dddc8a54dbf245d2bcff
+salsa20/1000 9ee7f7b5774db507d8e78fe7398594de9b40444a5301c14dfbc675e6310f9aa659e9cca9892563df9386a60607a2e18781d35d4897ea2b029db7b8819cafae17
+poly1305/1000 c403a63071ea2f2e732472db8e7b79c0
diff --git a/cbits/tests/fuzz/README b/cbits/tests/fuzz/README
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/README
@@ -0,0 +1,35 @@
+Generated bytes fed to the code that parses what comes off the wire.
+
+Rounds one to ten asked prepared questions.  This one asks whether anything
+breaks on input nobody chose.  What is looked for is memory safety rather
+than wrong answers: these inputs are meant to be rejected, and the question is
+how they are rejected.
+
+The harnesses are the places where bytes from elsewhere are taken apart:
+
+  ed25519  a public key and a signature, both the sender's to choose
+  decaf    point decoding, EdDSA public key decoding, Ed448 verification
+  p256     a point checked for being on the curve, then multiplied
+  aead     AES-GCM decryption, with the iv, aad and tag lengths from the wire
+  canary   the calibration
+
+fuzz_canary reads one byte past a buffer when the input opens with four
+particular bytes.  Four is the point: one chance in 2^32 puts it out of reach
+of throwing random input at the harness, and well within reach of a fuzzer
+that watches which comparisons it got past.  So a campaign that does not
+report the canary is not exploring, and the silence of the others would mean
+nothing.  Round five believed a ThreadSanitizer zero that meant nothing and
+round ten twice believed a scrubbing zero that meant nothing; this is cheaper
+than learning it a third time.
+
+The corpus is seeded with inputs each harness accepts -- a signature that
+verifies, the same with one bit of the message moved, a point that is on the
+curve, a ciphertext that authenticates -- so that a campaign starts from the
+far side of the checks rather than in front of them.  They were generated by
+running the primitives, and checked: the valid signature verifies, the
+tampered one does not, the point is on the curve.
+
+Where clang has no libFuzzer runtime -- Apple's does not -- run.sh replays the
+corpus and a deterministic stream through standalone.c instead.  That says the
+harnesses build and run clean under the sanitizers.  It explores nothing, and
+it says so rather than reporting a pass.
diff --git a/cbits/tests/fuzz/corpus/aead-authentic.bin b/cbits/tests/fuzz/corpus/aead-authentic.bin
new file mode 100644
Binary files /dev/null and b/cbits/tests/fuzz/corpus/aead-authentic.bin differ
diff --git a/cbits/tests/fuzz/corpus/ed25519-tampered.bin b/cbits/tests/fuzz/corpus/ed25519-tampered.bin
new file mode 100644
Binary files /dev/null and b/cbits/tests/fuzz/corpus/ed25519-tampered.bin differ
diff --git a/cbits/tests/fuzz/corpus/ed25519-valid.bin b/cbits/tests/fuzz/corpus/ed25519-valid.bin
new file mode 100644
Binary files /dev/null and b/cbits/tests/fuzz/corpus/ed25519-valid.bin differ
diff --git a/cbits/tests/fuzz/corpus/p256-on-curve.bin b/cbits/tests/fuzz/corpus/p256-on-curve.bin
new file mode 100644
Binary files /dev/null and b/cbits/tests/fuzz/corpus/p256-on-curve.bin differ
diff --git a/cbits/tests/fuzz/fuzz.h b/cbits/tests/fuzz/fuzz.h
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz.h
@@ -0,0 +1,34 @@
+/* Feeding generated bytes to the code that parses what comes off the wire.
+ *
+ * Each harness is an LLVMFuzzerTestOneInput, so a real fuzzer drives it.
+ * Where there is no fuzzer -- Apple's clang ships no libFuzzer runtime --
+ * standalone.c supplies a main that replays the committed corpus and then a
+ * deterministic stream of its own, which says the harness is wired up
+ * correctly and nothing about coverage.
+ *
+ * What is being looked for is memory safety, not wrong answers: these inputs
+ * are meant to be rejected, and the question is how they are rejected.
+ */
+#ifndef CRYPTON_TESTS_FUZZ_H
+#define CRYPTON_TESTS_FUZZ_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+/* Carve a fixed-width field out of the input.  Short input means the harness
+ * returns rather than reading past the end, which is the harness's own bug to
+ * avoid and not the library's to report. */
+static int fz_take(const uint8_t **p, size_t *left, void *out, size_t n)
+{
+	if (*left < n)
+		return 0;
+	memcpy(out, *p, n);
+	*p += n;
+	*left -= n;
+	return 1;
+}
+
+#endif
diff --git a/cbits/tests/fuzz/fuzz_aead.c b/cbits/tests/fuzz/fuzz_aead.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz_aead.c
@@ -0,0 +1,60 @@
+/* AES-GCM decryption, where the lengths and the tag are the sender's to
+ * choose.  The key is not attacker-controlled and is fixed here; what varies
+ * is everything that arrives with the message. */
+#include "tests/fuzz/fuzz.h"
+#include <stdlib.h>
+#include "crypton_aes.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	static const uint8_t key[16] = {
+		0x9e, 0x37, 0x79, 0xb9, 0x7f, 0x4a, 0x7c, 0x15,
+		0xf3, 0x9c, 0xc0, 0x60, 0x5c, 0xed, 0xc8, 0x34,
+	};
+	aes_key k;
+	aes_gcm_key gk;
+	uint8_t ivlen, aadlen, taglen;
+	const uint8_t *p = data;
+	size_t left = size;
+	uint8_t *out;
+
+	if (!fz_take(&p, &left, &ivlen, 1))
+		return 0;
+	if (!fz_take(&p, &left, &aadlen, 1))
+		return 0;
+	if (!fz_take(&p, &left, &taglen, 1))
+		return 0;
+
+	/* the three lengths are the sender's, so they are taken as they come,
+	 * short of asking for more bytes than arrived */
+	if (left < (size_t)ivlen + aadlen)
+		return 0;
+	taglen = (uint8_t)(taglen % 17);      /* 0..16, as the API allows */
+
+	{
+		const uint8_t *iv = p;
+		const uint8_t *aad = p + ivlen;
+		const uint8_t *ct = p + ivlen + aadlen;
+		size_t rest = left - ivlen - aadlen;
+		const uint8_t *tag;
+		size_t ctlen;
+
+		/* the tag arrives with the message, so it comes off the end */
+		if (rest < taglen)
+			return 0;
+		ctlen = rest - taglen;
+		tag = ct + ctlen;
+
+		out = (uint8_t *)malloc(ctlen + 1);
+		if (!out)
+			return 0;
+		crypton_aes_initkey(&k, (uint8_t *)key, sizeof key);
+		crypton_aes_gcm_key_init(&gk, &k);
+		(void)crypton_aes_gcm_full_decrypt(out, &gk, &k, (uint8_t *)iv, ivlen,
+		                                   (uint8_t *)aad, aadlen,
+		                                   (uint8_t *)ct, (uint32_t)ctlen,
+		                                   tag, taglen);
+		free(out);
+	}
+	return 0;
+}
diff --git a/cbits/tests/fuzz/fuzz_canary.c b/cbits/tests/fuzz/fuzz_canary.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz_canary.c
@@ -0,0 +1,41 @@
+/* The calibration.  This harness reads one byte past a buffer when the input
+ * opens with a four-byte marker.  Four bytes is the point: one chance in
+ * 2^32 puts it out of reach of throwing random input at the harness, while a
+ * fuzzer that watches which comparisons it got past finds it in seconds.  So
+ * a campaign that does not report this one is not fuzzing, and the silence of
+ * the harnesses beside it means nothing.
+ *
+ * Round five believed a ThreadSanitizer zero that meant nothing, and round
+ * ten twice believed a scrubbing zero that meant nothing.  This is cheaper
+ * than learning it a third time.
+ *
+ * Replaying the corpus is not expected to reach it, and run.sh says so.
+ */
+#include "tests/fuzz/fuzz.h"
+#include <stdlib.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	uint8_t *buf;
+	int r;
+
+	if (size < 5)
+		return 0;
+	if (data[0] != 0xde || data[1] != 0xad)
+		return 0;
+	if (data[2] != 0xbe || data[3] != 0xef)
+		return 0;
+
+	/* On the heap, not the stack.  A compiler that can see the size of a
+	 * local can also see that reading past it is undefined and remove the
+	 * read, which is what the first attempt at this did: the campaign found
+	 * nothing because by then there was nothing left to find.  It cannot
+	 * reason that way about what malloc returned. */
+	buf = (uint8_t *)malloc(16);
+	if (!buf)
+		return 0;
+	memset(buf, 0, 16);
+	r = buf[16] == data[4] ? 1 : 0;      /* deliberately one past the end */
+	free(buf);
+	return r;
+}
diff --git a/cbits/tests/fuzz/fuzz_decaf.c b/cbits/tests/fuzz/fuzz_decaf.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz_decaf.c
@@ -0,0 +1,40 @@
+/* Decoding a point and verifying an Ed448 signature, both from bytes that
+ * came from somewhere else.  point_decode validates; the EdDSA decode is the
+ * first thing a verifier does with a public key. */
+#include "tests/fuzz/fuzz.h"
+#include "decaf/point_448.h"
+#include "decaf/ed448.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	uint8_t ser[CRYPTON_DECAF_448_SER_BYTES];
+	uint8_t pub[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES];
+	uint8_t sig[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES];
+	crypton_decaf_448_point_t pt;
+	const uint8_t *p = data;
+	size_t left = size;
+	uint8_t selector;
+
+	if (!fz_take(&p, &left, &selector, 1))
+		return 0;
+
+	if (selector & 1) {
+		if (!fz_take(&p, &left, ser, sizeof ser))
+			return 0;
+		(void)crypton_decaf_448_point_decode(pt, ser, selector & 2 ? 1 : 0);
+		return 0;
+	}
+
+	if (!fz_take(&p, &left, pub, sizeof pub))
+		return 0;
+	if (selector & 2) {
+		(void)crypton_decaf_448_point_decode_like_eddsa_and_mul_by_ratio(pt, pub);
+		return 0;
+	}
+	if (!fz_take(&p, &left, sig, sizeof sig))
+		return 0;
+	/* a context of at most 255 bytes, as the API takes a uint8_t length */
+	(void)crypton_decaf_ed448_verify(sig, pub, p, left, selector & 4 ? 1 : 0,
+	                                 NULL, 0);
+	return 0;
+}
diff --git a/cbits/tests/fuzz/fuzz_ed25519.c b/cbits/tests/fuzz/fuzz_ed25519.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz_ed25519.c
@@ -0,0 +1,22 @@
+/* Ed25519 signature verification: the public key and the signature are both
+ * whatever the sender chose, and both are decoded before anything is
+ * checked. */
+#include "tests/fuzz/fuzz.h"
+#include "ed25519/ed25519.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	ed25519_public_key pk;
+	ed25519_signature sig;
+	const uint8_t *p = data;
+	size_t left = size;
+
+	if (!fz_take(&p, &left, pk, sizeof pk))
+		return 0;
+	if (!fz_take(&p, &left, sig, sizeof sig))
+		return 0;
+
+	/* whatever is left is the message */
+	(void)crypton_ed25519_sign_open(p, left, pk, sig);
+	return 0;
+}
diff --git a/cbits/tests/fuzz/fuzz_p256.c b/cbits/tests/fuzz/fuzz_p256.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/fuzz_p256.c
@@ -0,0 +1,33 @@
+/* A P-256 point as it arrives: two field elements, checked for being on the
+ * curve, and then multiplied if they are. */
+#include "tests/fuzz/fuzz.h"
+#include "p256/p256.h"
+
+void crypton_p256e_point_mul(const crypton_p256_int *n,
+    const crypton_p256_int *ix, const crypton_p256_int *iy,
+    crypton_p256_int *ox, crypton_p256_int *oy);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	uint8_t xb[P256_NBYTES], yb[P256_NBYTES], nb[P256_NBYTES];
+	crypton_p256_int x, y, n, ox, oy;
+	const uint8_t *p = data;
+	size_t left = size;
+
+	if (!fz_take(&p, &left, xb, sizeof xb))
+		return 0;
+	if (!fz_take(&p, &left, yb, sizeof yb))
+		return 0;
+	if (!fz_take(&p, &left, nb, sizeof nb))
+		return 0;
+
+	crypton_p256_from_bin(xb, &x);
+	crypton_p256_from_bin(yb, &y);
+	crypton_p256_from_bin(nb, &n);
+
+	if (crypton_p256_is_valid_point(&x, &y)) {
+		crypton_p256_mod(&crypton_SECP256r1_n, &n, &n);
+		crypton_p256e_point_mul(&n, &x, &y, &ox, &oy);
+	}
+	return 0;
+}
diff --git a/cbits/tests/fuzz/run.sh b/cbits/tests/fuzz/run.sh
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/run.sh
@@ -0,0 +1,132 @@
+#!/bin/sh
+# Generated bytes fed to the code that parses what comes off the wire.
+#
+# Each harness is an LLVMFuzzerTestOneInput.  With a clang that has the
+# libFuzzer runtime, each gets a bounded campaign under ASan and UBSan; with
+# one that does not -- Apple's, for instance -- standalone.c replays the
+# corpus and a deterministic stream instead, which says the harnesses are
+# wired up and nothing about coverage, and says so.
+#
+# fuzz_canary reads one byte past a buffer when the input opens with four
+# particular bytes.  One chance in 2^32 puts that out of reach of random
+# input and well within reach of a fuzzer that watches which comparisons it
+# got past, so a campaign that does not report it is not fuzzing, and the
+# silence of the others would mean nothing.
+#
+# Usage: cbits/tests/fuzz/run.sh [seconds-per-harness] [build-dir]
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
+secs=${1:-30}
+out=${2:-$(mktemp -d)}
+cc=${CC:-cc}
+mkdir -p "$out"
+cd "$root"
+
+D=cbits/decaf
+san="-fsanitize=address,undefined -fno-sanitize-recover=all"
+
+sources_for() {
+	case $1 in
+	canary)  echo "" ;;
+	ed25519) echo "cbits/ed25519/ed25519.c cbits/crypton_sha512.c" ;;
+	p256)    echo "cbits/p256/p256.c cbits/p256/p256_ec.c" ;;
+	aead)    echo "cbits/crypton_aes.c cbits/aes/generic.c cbits/aes/gf.c" ;;
+	decaf)   echo "$D/ed448goldilocks/decaf_all.c $D/ed448goldilocks/eddsa.c
+	               $D/ed448goldilocks/scalar.c $D/p448/f_arithmetic.c
+	               $D/p448/f_generic.c $D/utils.c
+	               $D/p448/arch_ref64/f_impl.c cbits/crypton_sha3.c" ;;
+	esac
+}
+includes_for() {
+	case $1 in
+	ed25519) echo "-Icbits/ed25519" ;;
+	decaf)   echo "-DCRYPTON_DECAF_WORD_BITS=64 -I$D/include -I$D/p448
+	               -I$D/include/arch_ref64 -I$D/p448/arch_ref64" ;;
+	*)       echo "" ;;
+	esac
+}
+
+# Is there a libFuzzer to drive these?
+have_fuzzer=no
+printf '#include <stdint.h>\n#include <stddef.h>\nint LLVMFuzzerTestOneInput(const uint8_t *d, size_t n){(void)d;(void)n;return 0;}\n' \
+	> "$out/probe.c"
+if $cc -fsanitize=fuzzer,address -o "$out/probe" "$out/probe.c" 2>/dev/null; then
+	have_fuzzer=yes
+fi
+
+status=0
+harnesses="canary ed25519 decaf p256 aead"
+
+for h in $harnesses; do
+	# shellcheck disable=SC2046,SC2086
+	$cc -O1 -g $san $(test $have_fuzzer = yes && echo -fsanitize=fuzzer) \
+		-Icbits -Icbits/include64 $(includes_for $h) \
+		-o "$out/fuzz_$h" "cbits/tests/fuzz/fuzz_$h.c" \
+		$(test $have_fuzzer = no && echo cbits/tests/fuzz/standalone.c) \
+		$(sources_for $h) 2> "$out/$h.cc" || {
+		echo "FAIL $h did not build"; sed -n '1,12p' "$out/$h.cc"; status=1; continue
+	}
+
+	if [ $have_fuzzer = no ]; then
+		"$out/fuzz_$h" cbits/tests/fuzz/corpus 20000 > "$out/$h.log" 2>&1 || true
+		if grep -qE "ERROR: |runtime error:" "$out/$h.log"; then
+			echo "FOUND $h: the sanitizers reported on replayed input"
+			grep -m1 -E "ERROR: |runtime error:" "$out/$h.log" | sed 's/^/    /'
+			status=1
+		else
+			echo "ran  $h ($(tail -1 "$out/$h.log"))"
+		fi
+		continue
+	fi
+
+	mkdir -p "$out/corpus-$h"
+	cp cbits/tests/fuzz/corpus/* "$out/corpus-$h/" 2>/dev/null || true
+	# -use_value_profile records the operands of comparisons, which is how a
+	# fuzzer gets past a check for particular bytes rather than waiting for
+	# them to come up at random.  The canary is exactly that check, and the
+	# parsers here are full of them.
+	"$out/fuzz_$h" "$out/corpus-$h" -max_total_time="$secs" \
+		-use_value_profile=1 -print_final_stats=1 \
+		> "$out/$h.log" 2>&1 || true
+
+	# What a find looks like.  AddressSanitizer writes "ERROR:", but
+	# UndefinedBehaviorSanitizer writes "runtime error:" and nothing else,
+	# so a detector that waits for "ERROR:" reads a campaign that found the
+	# canary as one that found nothing -- which is what the first three
+	# attempts at this file did.  libFuzzer's own line is the one that
+	# covers every case: it writes the input out whatever reported.
+	found=no
+	grep -qE "Test unit written to|ERROR: |runtime error:|deadly signal" \
+		"$out/$h.log" && found=yes
+
+	if [ "$h" = canary ]; then
+		if [ $found = no ]; then
+			echo "FAIL canary: the harness that reads out of bounds on a"
+			echo "     four-byte marker was not found in ${secs}s, so this"
+			echo "     campaign is not exploring and nothing below counts."
+			echo "     What it did do:"
+			tail -12 "$out/$h.log" | sed 's/^/       /'
+			status=1
+		else
+			echo "ok   canary: found, so the campaign explores"
+		fi
+		continue
+	fi
+
+	if [ $found = yes ]; then
+		echo "FOUND $h: the sanitizers reported"
+		grep -m1 -E "ERROR: |runtime error:|deadly signal" "$out/$h.log" |
+			sed 's/^/    /'
+		sed -n '/#0 /,/#8 /p' "$out/$h.log" | head -12 | sed 's/^/    /'
+		status=1
+	else
+		echo "ok   $h: $(grep -oE 'stat::number_of_executed_units: *[0-9]+' \
+			"$out/$h.log" | grep -oE '[0-9]+' | tail -1) inputs, nothing reported"
+	fi
+done
+
+if [ $have_fuzzer = no ]; then
+	echo "skip $cc has no libFuzzer, so the corpus was replayed and nothing explored"
+fi
+exit $status
diff --git a/cbits/tests/fuzz/standalone.c b/cbits/tests/fuzz/standalone.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/fuzz/standalone.c
@@ -0,0 +1,66 @@
+/* A main for the harnesses, for where there is no fuzzer.
+ *
+ * Apple's clang ships no libFuzzer runtime, so this replays the committed
+ * corpus and then a deterministic stream of generated inputs.  That says the
+ * harness is wired up and that the sanitizers are clean on what it feeds --
+ * it is not a fuzzing campaign and does not explore anything.  The campaign
+ * runs in CI, where clang has the runtime.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <dirent.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+static uint64_t s0 = 0x243f6a8885a308d3ULL, s1 = 0x13198a2e03707344ULL;
+static uint64_t rnd(void)
+{
+	uint64_t x = s0, y = s1;
+	s0 = y;
+	x ^= x << 23;
+	s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
+	return s1 + y;
+}
+
+int main(int argc, char **argv)
+{
+	static uint8_t buf[4096];
+	long rounds = argc > 2 ? strtol(argv[2], NULL, 10) : 20000;
+	long i;
+	int replayed = 0;
+
+	if (argc > 1) {
+		DIR *d = opendir(argv[1]);
+		struct dirent *e;
+		if (d) {
+			while ((e = readdir(d)) != NULL) {
+				char path[1024];
+				FILE *f;
+				size_t n;
+				if (e->d_name[0] == '.')
+					continue;
+				snprintf(path, sizeof path, "%s/%s", argv[1], e->d_name);
+				f = fopen(path, "rb");
+				if (!f)
+					continue;
+				n = fread(buf, 1, sizeof buf, f);
+				fclose(f);
+				LLVMFuzzerTestOneInput(buf, n);
+				replayed++;
+			}
+			closedir(d);
+		}
+	}
+
+	for (i = 0; i < rounds; i++) {
+		size_t n = (size_t)(rnd() % sizeof buf);
+		size_t j;
+		for (j = 0; j < n; j++)
+			buf[j] = (uint8_t)(rnd() >> 24);
+		LLVMFuzzerTestOneInput(buf, n);
+	}
+	printf("replayed %d corpus input(s), then %ld generated\n", replayed, rounds);
+	return 0;
+}
diff --git a/cbits/tests/scrub/README b/cbits/tests/scrub/README
new file mode 100644
--- /dev/null
+++ b/cbits/tests/scrub/README
@@ -0,0 +1,53 @@
+What is left in memory after a secret has been through it.
+
+Round eight asked whether a secret can be read from the time a primitive
+takes.  This asks whether it can be read from the memory afterwards.  The
+stack below a returning function is not erased -- it is simply no longer
+addressed -- and a context handed back to a caller is whatever the primitive
+left in it, so a later core file, crash dump or swapped page can carry a key
+away long after the caller believes it is done with it.
+
+Each probe paints the stack with a filler, runs a primitive on an
+unmistakable secret, copies the painted region away before anything can
+disturb it, and looks for the pattern.  Two things are asked separately:
+
+  scratch   what the primitive left below the caller's frame, in its own
+            working memory
+  context   what it left in the context object the caller still holds, which
+            is on the heap here as it is in crypton
+
+The first probe keeps the secret on purpose and has to be found.  That is not
+ceremony: the first two versions of this file reported that nothing was ever
+left behind, including by that probe, and both times the search was at fault.
+Once because the probed function was inlined into its caller, so its locals
+sat in a live frame rather than an abandoned one; once because the loop that
+copies the region away was turned into a call to memcpy, whose own frame
+landed exactly on the evidence.
+
+What this can say and what it cannot
+------------------------------------
+
+It finds a secret that survives *as it was handed over*.  It cannot find one
+that survives transformed, and the difference matters: Poly1305 reports
+nothing, but its finalize clears nothing either -- the key is clamped into r
+and pad, so it is still there and simply not byte-for-byte what was passed in.
+Read "no verbatim copy" as exactly that and no more.
+
+What it found
+-------------
+
+Nothing survives in any primitive's own scratch.  The RSA exponentiation is
+clean, which is worth saying because crypton_powm_sec memsets its table and
+then frees it, and a compiler is entitled to drop a store to memory that is
+about to die.  clang at -O2 keeps it -- the bzero is still there in the
+assembly, two instructions before the free -- but that is the compiler's
+choice rather than a guarantee, and explicit_bzero exists for this.
+
+Three contexts keep the secret as it was given: SHA-256, SHA-512 and
+ChaCha20.  The hash ones hold the buffered message, the ChaCha one holds the
+key.  Nothing clears any of them, in the C or in the Haskell above it, where
+Context is Bytes rather than ScrubbedBytes -- and hashFinalize copies the
+context before finalizing, so there are two of them per digest.  They are
+listed in known.txt; whether to clear them is a question about what a context
+means after it is finished with, and about the cost of scrubbing every hash,
+rather than something to settle here.
diff --git a/cbits/tests/scrub/known.txt b/cbits/tests/scrub/known.txt
new file mode 100644
--- /dev/null
+++ b/cbits/tests/scrub/known.txt
@@ -0,0 +1,16 @@
+# Places that keep a secret as it was handed over, which are known and not
+# treated as defects here.  A probe reporting only these passes; anything
+# else fails.
+
+# A hash context buffers the message a block at a time, so hashing a secret
+# leaves it in the context.  Nothing clears it: crypton_sha256_finalize and
+# its siblings compute the digest and return, and the Haskell side holds the
+# context as Bytes rather than ScrubbedBytes, so it is not cleared there
+# either.  hashFinalize copies the context before finalizing it, so there are
+# two such objects per digest rather than one.
+sha256    context
+sha512    context
+
+# crypton_chacha_init copies the key into the state, where it stays for the
+# life of the context.
+chacha20  context
diff --git a/cbits/tests/scrub/run.sh b/cbits/tests/scrub/run.sh
new file mode 100644
--- /dev/null
+++ b/cbits/tests/scrub/run.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# What is left on the stack after a secret has been through it.
+#
+# The stack below a returning function is not erased -- it is simply no longer
+# addressed -- so whatever a primitive kept there stays until something else
+# writes over it, and a later core file or swapped page carries it away.
+#
+# The driver paints the stack, runs each primitive on an unmistakable secret,
+# copies the painted region away before anything can disturb it, and looks for
+# the pattern.  The first probe keeps the secret on purpose and has to be
+# found; if it is not, the search is looking somewhere the calls do not use
+# and no other result counts.
+#
+# Not run under the sanitizers: reading the stack below the current frame is
+# exactly what this does, and ASan calls that an error.
+#
+# Usage: cbits/tests/scrub/run.sh [build-dir]
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
+out=${1:-$(mktemp -d)}
+cc=${CC:-cc}
+mkdir -p "$out"
+cd "$root"
+
+$cc -O2 -Icbits -Icbits/include64 -o "$out/scrub" cbits/tests/scrub/scrub.c \
+	cbits/crypton_sha256.c cbits/crypton_sha512.c cbits/crypton_chacha.c \
+	cbits/crypton_poly1305.c cbits/crypton_powm.c
+
+"$out/scrub"
diff --git a/cbits/tests/scrub/scrub.c b/cbits/tests/scrub/scrub.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/scrub/scrub.c
@@ -0,0 +1,271 @@
+/* What is left on the stack after a secret has been through it.
+ *
+ * The stack below a returning function is not erased -- it is simply no
+ * longer addressed -- so whatever the function kept there stays until
+ * something else writes over it.  For a hash context or a key schedule that
+ * means a copy of the key can outlive every object the caller thinks holds
+ * it, and a later crash dump, core file or swapped page carries it away.
+ *
+ * So: paint the stack with a filler, run the primitive on a secret made of
+ * an unmistakable pattern, copy the painted region somewhere else before
+ * anything can disturb it, and look for the pattern in the copy.  A hit is a
+ * place where the secret outlived the call.
+ *
+ * The region examined is below this file's own frame, so the driver's own
+ * copy of the secret is not what is being found.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Each probed function needs a frame of its own: inlined into probe, its
+ * locals would sit in a live frame rather than an abandoned one, and finding
+ * them there would mean nothing.  That cost the first attempt at this file. */
+#if defined(__GNUC__) || defined(__clang__)
+#define NOINLINE __attribute__((noinline))
+#else
+#define NOINLINE
+#endif
+
+/* 32 bytes that nothing else would produce */
+static const uint8_t SECRET[32] = {
+    0x9e, 0x37, 0x79, 0xb9, 0x7f, 0x4a, 0x7c, 0x15,
+    0xf3, 0x9c, 0xc0, 0x60, 0x5c, 0xed, 0xc8, 0x34,
+    0x1a, 0x2e, 0x8f, 0x5b, 0xd7, 0x06, 0x41, 0x92,
+    0xc3, 0x58, 0xe6, 0x70, 0xb1, 0x24, 0xaf, 0x8d,
+};
+
+#define REGION  (512 * 1024)
+#define FILLER  0x5a
+
+/* Write the filler over the stack the primitive is about to use.  Recursion
+ * rather than one large frame, so that the compiler cannot decide the whole
+ * thing is dead and skip it. */
+static void paint(int depth) {
+    volatile uint8_t pad[8192];
+    size_t i;
+    for (i = 0; i < sizeof pad; i++) pad[i] = FILLER;
+    if (depth > 0) paint(depth - 1);
+}
+
+/* How many times the pattern appears in the copy.  A run of the filler is
+ * what is expected; anything else is what was left behind. */
+static int count_hits(const uint8_t *hay, size_t n, const uint8_t *needle,
+                      size_t m) {
+    size_t i;
+    int hits = 0;
+    if (n < m) return 0;
+    for (i = 0; i + m <= n; i++)
+        if (hay[i] == needle[0] && memcmp(hay + i, needle, m) == 0) hits++;
+    return hits;
+}
+
+static uint8_t *snapshot;
+static int failures, checked;
+
+/* The context a primitive is handed, on the heap where crypton's own callers
+ * put it.  After the call it is looked at directly: whatever is still in it
+ * is what the caller is left holding. */
+static void *ctx_mem;
+static size_t ctx_len;
+
+/* known.txt lists the places that keep the secret and are understood.  A
+ * probe that reports only those passes; anything else is new and fails. */
+static int is_known(const char *name, const char *what) {
+    char line[256], want[128];
+    FILE *f = fopen("cbits/tests/scrub/known.txt", "r");
+    int found = 0;
+    if (!f) return 0;
+    snprintf(want, sizeof want, "%s %s", name, what);
+    while (fgets(line, sizeof line, f)) {
+        char a[64], b[64];
+        if (line[0] == '#' || sscanf(line, "%63s %63s", a, b) != 2) continue;
+        if (strcmp(a, name) == 0 && strcmp(b, what) == 0) { found = 1; break; }
+    }
+    fclose(f);
+    return found;
+}
+
+/* Run one primitive and report what it left.  The callback is handed the
+ * secret and is expected to use it and return. */
+static void probe(const char *name, void (*run)(const uint8_t *, size_t),
+                  size_t look_for) {
+    volatile uint8_t here;
+    const uint8_t *low;
+    int hits;
+
+    paint(24);                     /* about 200 KB of filler */
+    run(SECRET, sizeof SECRET);
+
+    /* Everything below this frame is what the call used.  Copied with a
+     * loop rather than memcpy: a call pushes a frame exactly where the one
+     * being examined was, and would erase the top of the evidence before it
+     * could be read.  That is how the first version of this reported that
+     * nothing was ever left behind, including by the canary. */
+    low = (const uint8_t *)&here - REGION;
+    {
+        /* volatile, or the compiler recognises the loop and emits memcpy --
+         * which is the call this loop exists to avoid.  That cost the first
+         * two attempts at this file. */
+        const volatile uint8_t *v = low;
+        size_t k;
+        for (k = 0; k < REGION; k++) snapshot[k] = v[k];
+    }
+
+    hits = count_hits(snapshot, REGION, SECRET, look_for);
+    checked++;
+    if (strcmp(name, "canary") == 0) {
+        if (hits == 0) {
+            printf("FAIL canary: the driver that keeps the secret on purpose\n"
+                   "     was not found, so nothing below this line counts\n");
+            failures++;
+        } else {
+            printf("ok   canary: found %d, so the search works\n", hits);
+        }
+        return;
+    }
+    /* two separate questions: what the primitive left in its own scratch,
+       and what it left in the context its caller still holds */
+    if (hits == 0) {
+        printf("ok   %-9s scratch: no verbatim copy below the frame\n", name);
+    } else if (is_known(name, "scratch")) {
+        printf("note %-9s scratch: %d verbatim copy(ies), known\n", name, hits);
+    } else {
+        printf("LEFT %-9s scratch: %d verbatim copy(ies) below the frame,\n"
+               "     and cbits/tests/scrub/known.txt does not list it\n",
+               name, hits);
+        failures++;
+    }
+    if (ctx_len) {
+        int chits = count_hits((const uint8_t *)ctx_mem, ctx_len, SECRET,
+                               look_for);
+        /* No hit is not the same as no secret.  A primitive that stores the
+           key transformed -- Poly1305 clamps it into r and pad -- keeps key
+           material the search cannot see.  All this can say is whether the
+           bytes survive as they were handed over. */
+        if (chits == 0) {
+            printf("ok   %-9s context: no verbatim copy of the secret\n",
+                   name);
+        } else if (is_known(name, "context")) {
+            printf("note %-9s context: %d verbatim copy(ies), known\n",
+                   name, chits);
+        } else {
+            printf("LEFT %-9s context: %d verbatim copy(ies) of the secret,\n"
+                   "     and cbits/tests/scrub/known.txt does not list it\n",
+                   name, chits);
+            failures++;
+        }
+        ctx_len = 0;
+    }
+}
+
+/* ---- the primitives ---------------------------------------------------- */
+
+#include "crypton_sha256.h"
+#include "crypton_sha512.h"
+#include "crypton_chacha.h"
+#include "crypton_poly1305.h"
+#include "crypton_powm.h"
+
+NOINLINE static void run_sha256(const uint8_t *s, size_t n) {
+    struct sha256_ctx *ctx = ctx_mem;
+    uint8_t out[32];
+    ctx_len = sizeof *ctx;
+    crypton_sha256_init(ctx);
+    crypton_sha256_update(ctx, s, (uint32_t)n);
+    crypton_sha256_finalize(ctx, out);
+    if (out[0] == 0xff && out[31] == 0xff) printf("unreachable\n");
+}
+
+NOINLINE static void run_sha512(const uint8_t *s, size_t n) {
+    struct sha512_ctx *ctx = ctx_mem;
+    uint8_t out[64];
+    ctx_len = sizeof *ctx;
+    crypton_sha512_init(ctx);
+    crypton_sha512_update(ctx, s, (uint32_t)n);
+    crypton_sha512_finalize(ctx, out);
+    if (out[0] == 0xff && out[63] == 0xff) printf("unreachable\n");
+}
+
+NOINLINE static void run_chacha(const uint8_t *s, size_t n) {
+    crypton_chacha_context *ctx = ctx_mem;
+    uint8_t iv[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+    uint8_t out[64];
+    ctx_len = sizeof *ctx;
+    crypton_chacha_init(ctx, 20, (uint32_t)n, s, sizeof iv, iv);
+    crypton_chacha_combine(out, ctx, out, sizeof out);
+    if (out[0] == 0xff && out[63] == 0xff) printf("unreachable\n");
+}
+
+NOINLINE static void run_poly1305(const uint8_t *s, size_t n) {
+    poly1305_ctx *ctx = ctx_mem;
+    poly1305_mac mac;
+    uint8_t msg[64];
+    /* the key is handed over where it already lies, so that nothing of it is
+       put on this frame by the driver rather than by the library */
+    (void)n;
+    memset(msg, 0x11, sizeof msg);
+    ctx_len = sizeof *ctx;
+    crypton_poly1305_init(ctx, (poly1305_key *)(void *)(uintptr_t)s);
+    crypton_poly1305_update(ctx, msg, sizeof msg);
+    crypton_poly1305_finalize(mac, ctx);
+    if (mac[0] == 0xff && mac[15] == 0xff) printf("unreachable\n");
+}
+
+/* The RSA private-key exponentiation.  Its scratch is on the heap, but the
+ * windows it selects and the accumulators pass through the stack. */
+static uint8_t *powm_out, *powm_base, *powm_mod, *powm_exp;
+NOINLINE static void run_powm(const uint8_t *s, size_t n) {
+    /* Everything is on the heap: the exponent because it is the secret and
+       must not be put on this frame by the driver, the rest to keep the
+       frame small enough that what is found below it came from the library. */
+    enum { LEN = 128 };
+    uint8_t *out = powm_out, *base = powm_base, *mod = powm_mod;
+    (void)s; (void)n;
+    if (crypton_powm_sec(out, base, LEN, powm_exp, LEN, mod, LEN) != 0)
+        printf("powm_sec refused\n");
+    if (out[0] == 0xff && out[LEN - 1] == 0xff) printf("unreachable\n");
+}
+
+/* The calibration.  This one keeps the secret on the stack on purpose, so it
+ * has to be found; if it is not, the painting or the snapshot is looking
+ * somewhere the calls do not use and every "ok" below means nothing. */
+NOINLINE static void run_canary(const uint8_t *s, size_t n) {
+    volatile uint8_t copy[128];
+    size_t i;
+    for (i = 0; i < n && i < sizeof copy; i++) copy[i] = s[i];
+    if (copy[0] == 0xff && copy[31] == 0xff) printf("unreachable\n");
+}
+
+int main(void) {
+    size_t i;
+    snapshot = malloc(REGION);
+    ctx_mem = malloc(4096);
+    powm_out = malloc(128); powm_base = malloc(128);
+    powm_mod = malloc(128); powm_exp = malloc(128);
+    if (!snapshot || !ctx_mem || !powm_out || !powm_base || !powm_mod || !powm_exp) return 2;
+    for (i = 0; i < 128; i++) {
+        powm_base[i] = (uint8_t)(i * 3 + 1);
+        powm_mod[i] = (uint8_t)(i * 5 + 7);
+        powm_exp[i] = SECRET[i % sizeof SECRET];
+    }
+    powm_mod[0] |= 0x80;
+    powm_mod[127] |= 1;
+    powm_base[0] &= 0x7f;
+
+    probe("canary", run_canary, 32);
+    probe("sha256", run_sha256, 32);
+    probe("sha512", run_sha512, 32);
+    probe("chacha20", run_chacha, 32);
+    probe("poly1305", run_poly1305, 16);
+    probe("powm_sec", run_powm, 32);
+
+    free(snapshot);
+    if (failures)
+        printf("\n%d place(s) keep the secret and are not in known.txt\n",
+               failures);
+    else
+        printf("\nnothing keeps the secret that known.txt does not name\n");
+    return failures != 0;
+}
diff --git a/cbits/tests/width/ed448_width.c b/cbits/tests/width/ed448_width.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/width/ed448_width.c
@@ -0,0 +1,87 @@
+/* Ed448 and X448 asked of the 32-bit field arithmetic and of the 64-bit one.
+   Only the f_impl.c under p448/arch_32 or p448/arch_ref64, and the two arch
+   include directories, differ between the builds; everything above them is
+   the same source. */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include "decaf/ed448.h"
+#include "decaf/point_448.h"
+
+static uint64_t s0 = 0x243f6a8885a308d3ULL, s1 = 0x13198a2e03707344ULL;
+static uint64_t rnd(void) {
+    uint64_t x = s0, y = s1;
+    s0 = y; x ^= x << 23;
+    s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
+    return s1 + y;
+}
+static void fill(uint8_t *p, size_t n) {
+    for (size_t i = 0; i < n; i++) p[i] = (uint8_t)(rnd() >> 24);
+}
+static void show(const char *t, const uint8_t *b, size_t n) {
+    printf("%s ", t);
+    for (size_t i = 0; i < n; i++) printf("%02x", b[i]);
+    printf("\n");
+}
+
+int main(void) {
+    uint8_t priv[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES];
+    uint8_t pub[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES];
+    uint8_t sig[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES];
+    uint8_t msg[256], ctx[8];
+    uint8_t xs[CRYPTON_DECAF_X448_PRIVATE_BYTES];
+    uint8_t xb[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+    uint8_t xo[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+
+    /* the scalars and points worth naming */
+    static const uint8_t edge[3] = {0x00, 0x01, 0xff};
+    for (unsigned e = 0; e < 3; e++) {
+        memset(priv, edge[e], sizeof priv);
+        crypton_decaf_ed448_derive_public_key(pub, priv);
+        show("epub", pub, sizeof pub);
+        crypton_decaf_ed448_sign(sig, priv, pub, (const uint8_t *)"", 0, 0, NULL, 0);
+        show("esig", sig, sizeof sig);
+        printf("everify=%d\n",
+            crypton_decaf_ed448_verify(sig, pub, (const uint8_t *)"", 0, 0, NULL, 0));
+
+        memset(xs, edge[e], sizeof xs);
+        crypton_decaf_x448_derive_public_key(xo, xs);
+        show("xpub", xo, sizeof xo);
+        memset(xb, edge[e], sizeof xb);
+        printf("x448=%d\n", crypton_decaf_x448(xo, xb, xs));
+        show("xsh", xo, sizeof xo);
+    }
+
+    for (int it = 0; it < 512; it++) {
+        size_t mlen = (size_t)(rnd() % sizeof msg);
+        uint8_t clen = (uint8_t)(rnd() % sizeof ctx);
+        fill(priv, sizeof priv);
+        fill(msg, sizeof msg);
+        fill(ctx, sizeof ctx);
+
+        crypton_decaf_ed448_derive_public_key(pub, priv);
+        show("pub", pub, sizeof pub);
+        crypton_decaf_ed448_sign(sig, priv, pub, msg, mlen, 0, ctx, clen);
+        show("sig", sig, sizeof sig);
+        printf("ok=%d bad=%d\n",
+            crypton_decaf_ed448_verify(sig, pub, msg, mlen, 0, ctx, clen),
+            crypton_decaf_ed448_verify(sig, pub, msg, mlen, 1, ctx, clen));
+        /* a signature with one bit moved has to fail on both builds alike */
+        sig[(size_t)(rnd() % sizeof sig)] ^= 1;
+        printf("tampered=%d\n",
+            crypton_decaf_ed448_verify(sig, pub, msg, mlen, 0, ctx, clen));
+
+        fill(xs, sizeof xs);
+        crypton_decaf_x448_derive_public_key(xb, xs);
+        show("xp", xb, sizeof xb);
+        uint8_t xs2[CRYPTON_DECAF_X448_PRIVATE_BYTES], xb2[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+        uint8_t sh1[CRYPTON_DECAF_X448_PUBLIC_BYTES], sh2[CRYPTON_DECAF_X448_PUBLIC_BYTES];
+        fill(xs2, sizeof xs2);
+        crypton_decaf_x448_derive_public_key(xb2, xs2);
+        int r1 = crypton_decaf_x448(sh1, xb2, xs);
+        int r2 = crypton_decaf_x448(sh2, xb, xs2);
+        printf("r=%d,%d agree=%d\n", r1, r2, memcmp(sh1, sh2, sizeof sh1) == 0);
+        show("sh", sh1, sizeof sh1);
+    }
+    return 0;
+}
diff --git a/cbits/tests/width/p256_width.c b/cbits/tests/width/p256_width.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/width/p256_width.c
@@ -0,0 +1,145 @@
+/* Exercise the public P-256 API and print everything it answers, so that the
+   32-bit build and the 64-bit build can be compared byte for byte.  Every
+   value crosses the boundary as big-endian bytes, which is the one form the
+   two representations agree on by construction. */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include "p256/p256.h"
+
+/* The header declares crypton_p256_point_mul and crypton_p256_modinv, and
+   nothing defines them.  What exists is this family, which has no header at
+   all -- the Haskell side declares it through the FFI. */
+void crypton_p256e_point_mul(const crypton_p256_int *n,
+    const crypton_p256_int *in_x, const crypton_p256_int *in_y,
+    crypton_p256_int *out_x, crypton_p256_int *out_y);
+void crypton_p256e_point_add(
+    const crypton_p256_int *in_x1, const crypton_p256_int *in_y1,
+    const crypton_p256_int *in_x2, const crypton_p256_int *in_y2,
+    crypton_p256_int *out_x, crypton_p256_int *out_y);
+void crypton_p256e_point_negate(
+    const crypton_p256_int *in_x, const crypton_p256_int *in_y,
+    crypton_p256_int *out_x, crypton_p256_int *out_y);
+void crypton_p256e_modadd(const crypton_p256_int *MOD,
+    const crypton_p256_int *a, const crypton_p256_int *b, crypton_p256_int *c);
+void crypton_p256e_modsub(const crypton_p256_int *MOD,
+    const crypton_p256_int *a, const crypton_p256_int *b, crypton_p256_int *c);
+void crypton_p256e_scalar_invert(const crypton_p256_int *a, crypton_p256_int *b);
+
+static uint64_t s0 = 0x243f6a8885a308d3ULL, s1 = 0x13198a2e03707344ULL;
+static uint64_t rnd(void) {           /* xoroshiro-ish, deterministic */
+    uint64_t x = s0, y = s1;
+    s0 = y;
+    x ^= x << 23;
+    s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
+    return s1 + y;
+}
+static void rnd_bytes(uint8_t *p, int n) {
+    for (int i = 0; i < n; i++) p[i] = (uint8_t)(rnd() >> 24);
+}
+static void show(const char *tag, const crypton_p256_int *v) {
+    uint8_t b[P256_NBYTES];
+    crypton_p256_to_bin(v, b);
+    printf("%s ", tag);
+    for (int i = 0; i < P256_NBYTES; i++) printf("%02x", b[i]);
+    printf("\n");
+}
+static void from_hex(const char *h, crypton_p256_int *out) {
+    uint8_t b[P256_NBYTES];
+    for (int i = 0; i < P256_NBYTES; i++) {
+        unsigned v; sscanf(h + 2 * i, "%2x", &v); b[i] = (uint8_t)v;
+    }
+    crypton_p256_from_bin(b, out);
+}
+
+int main(void) {
+    crypton_p256_int n, x, y, x2, y2, r, a, b, n2tmp;
+    uint8_t buf[P256_NBYTES];
+
+    show("order", &crypton_SECP256r1_n);
+    show("prime", &crypton_SECP256r1_p);
+    show("bparam", &crypton_SECP256r1_b);
+
+    /* the scalars worth naming: zero, one, the order and its neighbours, and
+       the all-bits-set shapes the comb recoding has to single out */
+    static const char *corners[] = {
+        "0000000000000000000000000000000000000000000000000000000000000000",
+        "0000000000000000000000000000000000000000000000000000000000000001",
+        "0000000000000000000000000000000000000000000000000000000000000002",
+        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* n */
+        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", /* n-1 */
+        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", /* n+1 */
+        "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+        "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+        "0000000000000000000000000000000000000000000000000000000000000000",
+    };
+    for (unsigned i = 0; i < sizeof corners / sizeof *corners; i++) {
+        from_hex(corners[i], &n);
+        crypton_p256_base_point_mul(&n, &x, &y);
+        printf("corner%u valid=%d\n", i, crypton_p256_is_valid_point(&x, &y));
+        show("  cx", &x); show("  cy", &y);
+    }
+
+    for (int it = 0; it < 1024; it++) {
+        rnd_bytes(buf, P256_NBYTES);
+        crypton_p256_from_bin(buf, &n);
+        crypton_p256_mod(&crypton_SECP256r1_n, &n, &n);
+        show("n", &n);
+
+        crypton_p256_base_point_mul(&n, &x, &y);
+        printf("valid=%d zero=%d odd=%d even=%d\n",
+               crypton_p256_is_valid_point(&x, &y),
+               crypton_p256_is_zero(&x), crypton_p256_is_odd(&y),
+               crypton_p256_is_even(&y));
+        show("x", &x); show("y", &y);
+
+        /* n2 * (that point), then n1*G + n2*P through the vartime pair */
+        rnd_bytes(buf, P256_NBYTES);
+        crypton_p256_from_bin(buf, &a);
+        crypton_p256_mod(&crypton_SECP256r1_n, &a, &a);
+        crypton_p256e_point_mul(&a, &x, &y, &x2, &y2);
+        show("px", &x2); show("py", &y2);
+        printf("pvalid=%d\n", crypton_p256_is_valid_point(&x2, &y2));
+
+        rnd_bytes(buf, P256_NBYTES);
+        crypton_p256_from_bin(buf, &b);
+        crypton_p256_mod(&crypton_SECP256r1_n, &b, &b);
+        crypton_p256_points_mul_vartime(&a, &b, &x, &y, &x2, &y2);
+        show("vx", &x2); show("vy", &y2);
+
+        /* the integer side: every arithmetic entry point the header offers */
+        crypton_p256_modmul(&crypton_SECP256r1_n, &a, 0, &b, &r); show("mul", &r);
+        crypton_p256_modmul(&crypton_SECP256r1_p, &a, 1, &b, &r); show("mulc", &r);
+        crypton_p256e_scalar_invert(&a, &r); show("inv", &r);
+        crypton_p256e_modadd(&crypton_SECP256r1_n, &a, &b, &r); show("madd", &r);
+        crypton_p256e_modsub(&crypton_SECP256r1_n, &a, &b, &r); show("msub", &r);
+        crypton_p256e_point_add(&x, &y, &x2, &y2, &r, &n2tmp); show("ax", &r); show("ay", &n2tmp);
+        crypton_p256e_point_negate(&x, &y, &r, &n2tmp); show("gx", &r); show("gy", &n2tmp);
+        crypton_p256_modinv_vartime(&crypton_SECP256r1_n, &a, &r); show("invv", &r);
+        printf("cmp=%d add=%d sub=%d addd=%d\n",
+               crypton_p256_cmp(&a, &b),
+               crypton_p256_add(&a, &b, &r),
+               crypton_p256_sub(&a, &b, &r),
+               crypton_p256_add_d(&a, 0x9e3779b9u, &r));
+        show("sum", &r);
+        /* the shifts are defined as n % P256_BITSPERDIGIT, which is 32 on one
+           build and 64 on the other, so keep the ask inside both */
+        /* a shift of nothing has to be the number itself.  Held here rather
+           than left to the random amounts below, because zero is the amount
+           that used to shift a digit by its own width. */
+        crypton_p256_shl(&a, 0, &r);
+        printf("shl0=%d ", crypton_p256_cmp(&a, &r) == 0);
+        crypton_p256_shr(&a, 0, &r);
+        printf("shr0=%d\n", crypton_p256_cmp(&a, &r) == 0);
+        for (int s = 0; s < 3; s++) {
+            int k = (int)(rnd() % 32);
+            printf("shl%d=%d\n", k, (int)(crypton_p256_shl(&a, k, &r) & 0xff));
+            show("shl", &r);
+            crypton_p256_shr(&a, k, &r); show("shr", &r);
+        }
+        for (int bit = 0; bit < 256; bit += 37)
+            printf("bit%d=%d ", bit, crypton_p256_get_bit(&a, bit));
+        printf("\n");
+    }
+    return 0;
+}
diff --git a/cbits/tests/width/run.sh b/cbits/tests/width/run.sh
new file mode 100644
--- /dev/null
+++ b/cbits/tests/width/run.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# The three implementations that only a 32-bit architecture receives, asked
+# the same questions as the 64-bit ones they stand in for.
+#
+#   cbits/include32/p256          against  cbits/include64/p256
+#   cbits/curve25519-donna.c      against  curve25519-donna-c64.c
+#   cbits/decaf/p448/arch_32      against  cbits/decaf/p448/arch_ref64
+#
+# No job in the matrix is 32-bit, so until this ran, none of the left column
+# had ever been compiled, let alone executed.  The two sides of each pair
+# define the same symbols, so they cannot share a binary: each driver is built
+# twice and the two outputs compared.
+#
+# With a compiler that can target 32-bit x86 -- gcc-multilib on the Linux
+# runner -- the 32-bit side is built a second time as a real 32-bit binary,
+# which is the only way to see what the narrower int, size_t and pointer do.
+#
+# Usage: cbits/tests/width/run.sh [build-dir]
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
+out=${1:-$(mktemp -d)}
+cc=${CC:-cc}
+mkdir -p "$out"
+cd "$root"
+
+D=cbits/decaf
+decaf_common="$D/ed448goldilocks/decaf_all.c $D/ed448goldilocks/eddsa.c
+              $D/ed448goldilocks/scalar.c $D/p448/f_arithmetic.c
+              $D/p448/f_generic.c $D/utils.c cbits/crypton_sha3.c"
+
+# name, the flags and sources for the 64-bit side, then for the 32-bit side
+build() {
+	# shellcheck disable=SC2086
+	$cc -O2 -Wno-deprecated-declarations $EXTRA -o "$out/$1" $2 2>&1 |
+		grep -vE "^$|deprecated" || true
+	test -x "$out/$1" || { echo "did not build: $1"; exit 1; }
+}
+
+status=0
+compare() {
+	if cmp -s "$out/$1.txt" "$out/$2.txt"; then
+		echo "ok   $3 ($(wc -l < "$out/$1.txt" | tr -d ' ') lines)"
+	else
+		echo "FAIL $3"
+		diff "$out/$1.txt" "$out/$2.txt" | head -20
+		status=1
+	fi
+}
+
+for width in 64 32; do
+	case $width in
+	64) p256_inc=cbits/include64; donna=cbits/curve25519/curve25519-donna-c64.c; arch=arch_ref64 ;;
+	32) p256_inc=cbits/include32; donna=cbits/curve25519/curve25519-donna.c;     arch=arch_32    ;;
+	esac
+
+	# decaf decides its word size twice and from two different things: the
+	# field limbs from ARCH_WORD_BITS, which follows the arch directory
+	# picked above, and the scalar limbs from CRYPTON_DECAF_WORD_BITS, which
+	# common.h reads off the host compiler.  On a 32-bit machine -- the only
+	# place cabal asks for arch_32 -- both come out 32.  Here the host is
+	# 64-bit whichever side is being built, so say which is wanted rather
+	# than compile a half-32-bit-half-64-bit library and compare that.
+
+	EXTRA="-Icbits -I$p256_inc"
+	build "p256_$width" "cbits/tests/width/p256_width.c cbits/p256/p256.c cbits/p256/p256_ec.c"
+
+	EXTRA="-Icbits"
+	build "x25519_$width" "cbits/tests/width/x25519_width.c $donna"
+
+	EXTRA="-DCRYPTON_DECAF_WORD_BITS=$width -Icbits -I$D/include -I$D/p448 -I$D/include/$arch -I$D/p448/$arch"
+	build "ed448_$width" "cbits/tests/width/ed448_width.c $decaf_common $D/p448/$arch/f_impl.c"
+
+	for t in p256 x25519 ed448; do
+		"$out/${t}_$width" > "$out/${t}_$width.txt"
+	done
+done
+
+for t in p256 x25519 ed448; do
+	compare "${t}_64" "${t}_32" "$t: the 32-bit implementation answers what the 64-bit one answers"
+done
+
+# The same sources again, this time actually narrow.  Only the 32-bit side is
+# tried: the 64-bit P-256 wants __uint128_t, which a 32-bit target has not got,
+# which is the whole reason the 32-bit side exists.
+printf 'int main(void){return 0;}\n' > "$out/probe.c"
+if $cc -m32 -o "$out/probe" "$out/probe.c" 2>/dev/null && "$out/probe"; then
+	EXTRA="-m32 -Icbits -Icbits/include32"
+	build p256_m32 "cbits/tests/width/p256_width.c cbits/p256/p256.c cbits/p256/p256_ec.c"
+	EXTRA="-m32 -Icbits"
+	build x25519_m32 "cbits/tests/width/x25519_width.c cbits/curve25519/curve25519-donna.c"
+	EXTRA="-m32 -DCRYPTON_DECAF_WORD_BITS=32 -Icbits -I$D/include -I$D/p448 -I$D/include/arch_32 -I$D/p448/arch_32"
+	build ed448_m32 "cbits/tests/width/ed448_width.c $decaf_common $D/p448/arch_32/f_impl.c"
+
+	for t in p256 x25519 ed448; do
+		"$out/${t}_m32" > "$out/${t}_m32.txt"
+		compare "${t}_32" "${t}_m32" "$t: a 32-bit host answers what a 64-bit host answers"
+	done
+else
+	echo "skip $cc cannot build and run a 32-bit binary here; the comparison above still ran"
+fi
+
+exit $status
diff --git a/cbits/tests/width/x25519_width.c b/cbits/tests/width/x25519_width.c
new file mode 100644
--- /dev/null
+++ b/cbits/tests/width/x25519_width.c
@@ -0,0 +1,74 @@
+/* The same X25519 asked of the 32-bit donna and the 64-bit donna.  Both files
+   define crypton_curve25519_donna, so they cannot share a binary: build twice
+   and compare. */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+void crypton_curve25519_donna(uint8_t *mypublic, const uint8_t *secret,
+                              const uint8_t *basepoint);
+
+static uint64_t s0 = 0x243f6a8885a308d3ULL, s1 = 0x13198a2e03707344ULL;
+static uint64_t rnd(void) {
+    uint64_t x = s0, y = s1;
+    s0 = y; x ^= x << 23;
+    s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
+    return s1 + y;
+}
+static void show(const char *t, const uint8_t *b) {
+    printf("%s ", t);
+    for (int i = 0; i < 32; i++) printf("%02x", b[i]);
+    printf("\n");
+}
+
+int main(void) {
+    uint8_t sec[32], base[32], out[32];
+    /* the named points: the generator, zero, one, the low-order points and
+       the all-ones field element that reduces to nothing */
+    static const uint8_t corners[][32] = {
+        {9},
+        {0},
+        {1},
+        {0xe0,0xeb,0x7a,0x7c,0x3b,0x41,0xb8,0xae,0x16,0x56,0xe3,0xfa,0xf1,0x9f,
+         0xc4,0x6a,0xda,0x09,0x8d,0xeb,0x9c,0x32,0xb1,0xfd,0x86,0x62,0x05,0x16,
+         0x5f,0x49,0xb8,0x00},
+        {0x5f,0x9c,0x95,0xbc,0xa3,0x50,0x8c,0x24,0xb1,0xd0,0xb1,0x55,0x9c,0x83,
+         0xef,0x5b,0x04,0x44,0x5c,0xc4,0x58,0x1c,0x8e,0x86,0xd8,0x22,0x4e,0xdd,
+         0xd0,0x9f,0x11,0x57},
+        {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+         0xff,0xff,0xff,0xff},
+        {0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f},
+    };
+    for (unsigned c = 0; c < sizeof corners / sizeof *corners; c++) {
+        memset(sec, 0, 32);
+        sec[0] = (uint8_t)(0x40 + c); sec[31] = 0x40;
+        crypton_curve25519_donna(out, sec, corners[c]);
+        show("corner", out);
+        /* and the scalars with every clamped bit at an edge */
+        memset(sec, 0xff, 32); sec[0] = 0xf8; sec[31] = 0x7f;
+        crypton_curve25519_donna(out, sec, corners[c]);
+        show("cmax", out);
+        memset(sec, 0x00, 32); sec[31] = 0x40;
+        crypton_curve25519_donna(out, sec, corners[c]);
+        show("cmin", out);
+    }
+    for (int it = 0; it < 2048; it++) {
+        for (int i = 0; i < 32; i++) sec[i] = (uint8_t)(rnd() >> 24);
+        for (int i = 0; i < 32; i++) base[i] = (uint8_t)(rnd() >> 24);
+        crypton_curve25519_donna(out, sec, base);
+        show("r", out);
+        /* and a round trip: the shared secret both sides should agree on */
+        uint8_t pa[32], pb[32], sa[32], sb[32], g[32] = {9};
+        uint8_t s2[32];
+        for (int i = 0; i < 32; i++) s2[i] = (uint8_t)(rnd() >> 24);
+        crypton_curve25519_donna(pa, sec, g);
+        crypton_curve25519_donna(pb, s2, g);
+        crypton_curve25519_donna(sa, sec, pb);
+        crypton_curve25519_donna(sb, s2, pa);
+        printf("agree=%d\n", memcmp(sa, sb, 32) == 0);
+        show("sa", sa);
+    }
+    return 0;
+}
diff --git a/crypton.cabal b/crypton.cabal
--- a/crypton.cabal
+++ b/crypton.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               crypton
-version:            2.1.2
+version:            2.1.3
 license:            BSD-3-Clause
 license-file:       LICENSE
 copyright:          Vincent Hanquez <vincent@snarc.org>
@@ -12,31 +12,11 @@
 
 homepage:           https://github.com/kazu-yamamoto/crypton
 bug-reports:        https://github.com/kazu-yamamoto/crypton/issues
-synopsis:           Cryptography Primitives sink
-description:
-    A repository of cryptographic primitives.
-    .
-    * Symmetric ciphers: AES, DES, 3DES, CAST5, Blowfish, Twofish, Camellia, RC4, Salsa, XSalsa, ChaCha.
-    .
-    * Hash: SHA1, SHA2, SHA3, SHAKE, MD2, MD4, MD5, Keccak, Skein, Ripemd, Tiger, Whirlpool, Blake2
-    .
-    * MAC: HMAC, KMAC, Poly1305
-    .
-    * Asymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Curve448, Ed25519, Ed448
-    .
-    * Key Derivation Function: PBKDF2, Scrypt, HKDF, Argon2, BCrypt, BCryptPBKDF
-    .
-    * Cryptographic Random generation: System Entropy, Deterministic Random Generator
-    .
-    * Data related: Anti-Forensic Information Splitter (AFIS)
-    .
-    If anything cryptographic related is missing from here, submit
-    a pull request to have it added. This package strives to be a
-    cryptographic kitchen sink that provides cryptography for everyone.
-    .
-    Evaluate the security related to your requirements before using.
-    .
-    Read "Crypto.Tutorial" for a quick start guide.
+synopsis:           Cryptography Primitives
+description:        `crypton` is a low-level cryptography library.
+                    To achieve high performance, it utilizes C and assembly
+                    language to define FFI bindings, structuring them
+                    in a way that makes them easy to use.
 
 category:           Cryptography
 build-type:         Simple
@@ -46,6 +26,7 @@
     cbits/curve25519/*.h
     cbits/aes/armv8_impl.c
     cbits/aes/x86ni_impl.c
+    cbits/LICENSE.go
     cbits/asm/LICENSE.cryptogams
     cbits/asm/README.md
     cbits/asm/aesni-gcm-x86_64.pl
@@ -88,6 +69,25 @@
     cbits/s2n/import.sh
     cbits/s2n/include/*.h
     cbits/s2n/x86_att/*.S
+    cbits/tests/ct/*.c
+    cbits/tests/ct/*.h
+    cbits/tests/ct/README
+    cbits/tests/ct/run.sh
+    cbits/tests/endian/*.c
+    cbits/tests/endian/README
+    cbits/tests/endian/run.sh
+    cbits/tests/endian/vectors.txt
+    cbits/tests/fuzz/*.c
+    cbits/tests/fuzz/*.h
+    cbits/tests/fuzz/README
+    cbits/tests/fuzz/corpus/*.bin
+    cbits/tests/fuzz/run.sh
+    cbits/tests/scrub/*.c
+    cbits/tests/scrub/README
+    cbits/tests/scrub/known.txt
+    cbits/tests/scrub/run.sh
+    cbits/tests/width/*.c
+    cbits/tests/width/run.sh
     tests/*.hs
 
 extra-doc-files:
@@ -117,7 +117,11 @@
     manual:      True
 
 flag support_sse
-    description: Use SSE optimized version of (BLAKE2, ARGON2)
+    description:
+        Use SSE optimized version of (BLAKE2, ARGON2) on i386.  x86-64 takes
+        them anyway; every other architecture has no SSE to offer and ignores
+        this flag, rather than failing to compile the sources.
+
     default:     False
     manual:      True
 
@@ -291,6 +295,7 @@
         cbits/crypton_whirlpool.c
         cbits/crypton_xsalsa.c
         cbits/ed25519/ed25519.c
+        cbits/ed25519/ed25519_s2n.c
         cbits/p256/p256.c
         cbits/p256/p256_ec.c
 
@@ -362,12 +367,11 @@
     ghc-options:      -Wall -fwarn-tabs -optc-O3
     build-depends:
         base >=4.13 && <5,
-        bytestring,
-        primitive >=0.9,
-        deepseq,
-        base16 >=1.0,
-        bytestring,
-        text,
+        bytestring <0.13,
+        primitive >=0.9 && <0.10,
+        deepseq <1.6,
+        base16 >=1.0 && <1.1,
+        text <2.2,
         ram >=0.20.1 && <0.23
 
     if flag(old_toolchain_inliner)
@@ -391,6 +395,17 @@
 
         include-dirs: cbits/decaf/include/arch_ref64 cbits/decaf/p448/arch_ref64
 
+        -- decaf sizes its field limbs from the arch directory just chosen and
+        -- its scalar limbs from a separate macro that cbits/decaf/include/
+        -- decaf/common.h works out from the compiler, by asking after
+        -- __x86_64__ and the width of uint_fast32_t.  The two answers need
+        -- not agree: on Apple Silicon uint_fast32_t is four bytes, so the
+        -- same aarch64 CPU takes 64-bit field limbs and 32-bit scalar limbs,
+        -- where on Linux it takes 64-bit for both.  Ed448 signing pays 5.5%
+        -- for that (20.69 us against 19.56 on an M4).  The architecture is
+        -- already decided here, so decide this with it.
+        cc-options: -DCRYPTON_DECAF_WORD_BITS=64
+
     else
         c-sources:
             cbits/decaf/ed448goldilocks/decaf_all.c
@@ -402,6 +417,7 @@
             cbits/decaf/utils.c
 
         include-dirs: cbits/decaf/include/arch_32 cbits/decaf/p448/arch_32
+        cc-options: -DCRYPTON_DECAF_WORD_BITS=32
 
     if ((((((((arch(x86_64) || arch(aarch64)) || arch(loongarch64)) || arch(ppc64le)) || arch(riscv64)) || arch(s390x)) || arch(alpha)) || arch(ppc64)) || arch(sparc64))
         c-sources: cbits/curve25519/curve25519-donna-c64.c
@@ -487,6 +503,8 @@
             cbits/crypton_ecc_s2n.c
             cbits/p256/p256_base_table.c
             cbits/p256/p256_s2n.c
+            cbits/p256/p256_verify.c
+            cbits/p256/p256_wnaf_table.c
 
         if arch(aarch64)
             asm-sources:
@@ -496,6 +514,9 @@
                 cbits/s2n/arm/curve25519_x25519_alt.S
                 cbits/s2n/arm/curve25519_x25519base.S
                 cbits/s2n/arm/curve25519_x25519base_alt.S
+                cbits/s2n/arm/edwards25519_encode.S
+                cbits/s2n/arm/edwards25519_scalarmulbase.S
+                cbits/s2n/arm/edwards25519_scalarmulbase_alt.S
                 cbits/s2n/arm/bignum_inv_p521.S
                 cbits/s2n/arm/bignum_montinv_p384.S
                 cbits/s2n/arm/bignum_montmul_p384.S
@@ -507,6 +528,15 @@
                 cbits/s2n/arm/bignum_sqr_p521.S
                 cbits/s2n/arm/bignum_sqr_p521_alt.S
                 cbits/s2n/arm/bignum_tomont_p384.S
+                cbits/s2n/arm/bignum_demont_p256.S
+                cbits/s2n/arm/bignum_neg_p256.S
+                cbits/s2n/arm/bignum_tomont_p256.S
+                cbits/s2n/arm/p256_montjadd.S
+                cbits/s2n/arm/p256_montjadd_alt.S
+                cbits/s2n/arm/p256_montjdouble.S
+                cbits/s2n/arm/p256_montjdouble_alt.S
+                cbits/s2n/arm/p256_montjmixadd.S
+                cbits/s2n/arm/p256_montjmixadd_alt.S
                 cbits/s2n/arm/p256_scalarmul.S
                 cbits/s2n/arm/p256_scalarmul_alt.S
                 cbits/s2n/arm/p256_scalarmulbase.S
@@ -524,6 +554,9 @@
                 cbits/s2n/x86_att/curve25519_x25519_alt.S
                 cbits/s2n/x86_att/curve25519_x25519base.S
                 cbits/s2n/x86_att/curve25519_x25519base_alt.S
+                cbits/s2n/x86_att/edwards25519_encode.S
+                cbits/s2n/x86_att/edwards25519_scalarmulbase.S
+                cbits/s2n/x86_att/edwards25519_scalarmulbase_alt.S
                 cbits/s2n/x86_att/bignum_deamont_p384_alt.S
                 cbits/s2n/x86_att/bignum_inv_p521.S
                 cbits/s2n/x86_att/bignum_montinv_p384.S
@@ -537,6 +570,17 @@
                 cbits/s2n/x86_att/bignum_sqr_p521_alt.S
                 cbits/s2n/x86_att/bignum_tomont_p384.S
                 cbits/s2n/x86_att/bignum_tomont_p384_alt.S
+                cbits/s2n/x86_att/bignum_demont_p256.S
+                cbits/s2n/x86_att/bignum_demont_p256_alt.S
+                cbits/s2n/x86_att/bignum_neg_p256.S
+                cbits/s2n/x86_att/bignum_tomont_p256.S
+                cbits/s2n/x86_att/bignum_tomont_p256_alt.S
+                cbits/s2n/x86_att/p256_montjadd.S
+                cbits/s2n/x86_att/p256_montjadd_alt.S
+                cbits/s2n/x86_att/p256_montjdouble.S
+                cbits/s2n/x86_att/p256_montjdouble_alt.S
+                cbits/s2n/x86_att/p256_montjmixadd.S
+                cbits/s2n/x86_att/p256_montjmixadd_alt.S
                 cbits/s2n/x86_att/p256_scalarmul.S
                 cbits/s2n/x86_att/p256_scalarmul_alt.S
                 cbits/s2n/x86_att/p256_scalarmulbase.S
@@ -665,6 +709,12 @@
                     -- 128-bit throughout.  crypton_cpu.c asks the
                     -- processor before any of it runs.
                     cbits/aes/gcm_vaes_x86.c
+                    -- and the 512-bit form, four blocks to each, which Ice
+                    -- Lake and Zen 4 onwards have.  Same story about
+                    -- borrowing, and the same run-time question -- with
+                    -- three more bits of XCR0 in it, since these need the
+                    -- operating system to save the AVX-512 state.
+                    cbits/aes/gcm_vaes512_x86.c
                     cbits/aes/gcm_x86_asm.c
 
                 if os(osx)
@@ -687,7 +737,7 @@
             cbits/aes/gf.c
             cbits/crypton_aes.c
 
-    if (arch(x86_64) || flag(support_sse))
+    if (arch(x86_64) || (flag(support_sse) && arch(i386)))
         c-sources:
             cbits/blake2/sse/blake2b.c
             cbits/blake2/sse/blake2bp.c
@@ -705,7 +755,7 @@
 
         include-dirs: cbits/blake2/ref
 
-    if (arch(x86_64) || flag(support_sse))
+    if (arch(x86_64) || (flag(support_sse) && arch(i386)))
         cpp-options: -DSUPPORT_SSE
 
         if arch(i386)
@@ -715,13 +765,13 @@
         cpp-options:     -DWINDOWS
         other-modules:   Crypto.Random.Entropy.Windows
         extra-libraries: advapi32
-        build-depends:   Win32
+        build-depends:   Win32 <2.15
 
     else
         other-modules: Crypto.Random.Entropy.Unix
 
     if (impl(ghc >=0) && flag(integer-gmp))
-        build-depends: integer-gmp
+        build-depends: integer-gmp <1.2
 
     if flag(support_deepseq)
         cpp-options:   -DWITH_DEEPSEQ_SUPPORT
diff --git a/tests/BlockCipher/AESSpec.hs b/tests/BlockCipher/AESSpec.hs
--- a/tests/BlockCipher/AESSpec.hs
+++ b/tests/BlockCipher/AESSpec.hs
@@ -3,6 +3,7 @@
 module BlockCipher.AESSpec (spec) where
 
 import BlockCipher
+import Control.Exception (evaluate)
 import qualified Crypto.Cipher.AES as AES
 import Crypto.Cipher.Types
 import Crypto.Error
@@ -256,6 +257,67 @@
     it "refuses input shorter than the tag" $
         (GCM.decrypt ctx16 iv16 B.empty (B.replicate 8 0) 16 :: Maybe B.ByteString)
             `shouldBe` Nothing
+    it "refuses a ciphertext with no authentication tag" $
+        let sealed = GCM.encrypt ctx16 iv16 header message 16 :: B.ByteString
+            body = B.take (B.length sealed - 16) sealed
+         in (GCM.decrypt ctx16 iv16 header body 0 :: Maybe B.ByteString)
+                `shouldBe` Nothing
+    it "does not authenticate an altered ciphertext with a zero-length tag" $
+        let sealed = GCM.encrypt ctx16 iv16 header message 16 :: B.ByteString
+            body = B.take (B.length sealed - 16) sealed
+         in (GCM.decrypt ctx16 iv16 header (flipFirst body) 0 :: Maybe B.ByteString)
+                `shouldBe` Nothing
+    -- Shorter than four bytes the tag authenticates next to nothing, and
+    -- longer than sixteen there is no more tag for GCM to give.
+    describe "refuses a tag length outside 4 to 16 bytes" $
+        forM_ [0, 3, 17 :: Int] $ \taglen -> describe (show taglen) $ do
+            it "encrypt" $
+                evaluate (GCM.encrypt ctx16 iv16 header message taglen :: B.ByteString)
+                    `shouldThrow` (== CryptoError_AuthenticationTagSizeInvalid)
+            it "decrypt" $
+                (GCM.decrypt ctx16 iv16 header plainSealed taglen :: Maybe B.ByteString)
+                    `shouldBe` Nothing
+            it "decryptWithTag" $
+                evaluate
+                    ( GCM.decryptWithTag ctx16 iv16 header message taglen
+                        :: (B.ByteString, AuthTag)
+                    )
+                    `shouldThrow` (== CryptoError_AuthenticationTagSizeInvalid)
+            it "encryptWithMask" $
+                withMaskTag taglen 0 `shouldReturn` Nothing
+    -- SP 800-38D 5.2.1.1 wants at least one byte of IV.  With none, GCM's
+    -- pre-counter block is zero and the tag of a message is
+    -- GHASH_H(A, C) XOR E(K, 0^128) -- and E(K, 0^128) is the GHASH key H
+    -- itself.  One full tag therefore gives H away, H belongs to the key
+    -- rather than to the nonce, and with it a tag can be forged for any
+    -- message under any nonce the key has been used with, twelve-byte ones
+    -- included.  The general interface has refused the empty IV since
+    -- f98cff3 and these four did not.
+    describe "refuses a nonce of no bytes" $ do
+        it "encrypt" $
+            evaluate (GCM.encrypt ctx16 B.empty header message 16 :: B.ByteString)
+                `shouldThrow` (== CryptoError_IvSizeInvalid)
+        -- a message that really is sealed under the empty nonce, so that this
+        -- says something whether or not `encrypt` refuses one: before the
+        -- check, `decrypt` returned the sixteen bytes of plaintext for it
+        it "decrypt, on a message that is genuine under it" $
+            (GCM.decrypt ctx16 B.empty header emptyNonceSealed 16 :: Maybe B.ByteString)
+                `shouldBe` Nothing
+        it "decryptWithTag" $
+            evaluate
+                ( GCM.decryptWithTag ctx16 B.empty header message 16
+                    :: (B.ByteString, AuthTag)
+                )
+                `shouldThrow` (== CryptoError_IvSizeInvalid)
+        it "encryptWithMask, writing nothing" $
+            withMaskIv B.empty 16 4 `shouldReturn` Nothing
+    -- and only the empty one: SP 800-38D allows every length from one byte up,
+    -- so this must not become a check for twelve
+    it "takes a nonce of one byte" $
+        let iv1 = B.singleton 0x77
+            sealed = GCM.encrypt ctx16 iv1 header message 16 :: B.ByteString
+         in (GCM.decrypt ctx16 iv1 header sealed 16 :: Maybe B.ByteString)
+                `shouldBe` Just message
     describe "header protection" $ do
         it "writes the ciphertext encrypt gives" $
             withMask 4 `shouldReturn` Just (plainSealed, expectedMask 4)
@@ -297,14 +359,21 @@
     message = "a packet payload" :: B.ByteString
     header = "\x40\x01\x02\x03" :: B.ByteString
     plainSealed = GCM.encrypt ctx16 iv16 header message 16 :: B.ByteString
+    -- ctx16, no nonce at all, `header` as the additional data and `message`
+    -- as the plaintext, taken from the tree before the check went in
+    emptyNonceSealed =
+        "\x09\x25\xea\x53\x9b\x98\xf1\x0e\x02\x5f\x8a\x70\x8d\xf4\x6d\xb2\xf2\xce\x43\x31\x67\x12\x32\xef\x29\xcc\x69\x52\x12\x98\xd1\xf3"
+            :: B.ByteString
     -- the buffers the caller owns, as a packet writer would have them
-    withMask off =
-        allocaBytes (B.length message + 16) $ \outp ->
+    withMask = withMaskTag 16
+    withMaskTag = withMaskIv iv16
+    withMaskIv iv taglen off =
+        allocaBytes (B.length message + taglen) $ \outp ->
             allocaBytes 16 $ \maskp -> do
-                ok <- GCM.encryptWithMask ctx16 hpKey iv16 header message 16 off outp maskp
+                ok <- GCM.encryptWithMask ctx16 hpKey iv header message taglen off outp maskp
                 if ok
                     then do
-                        sealed <- B.packCStringLen (castPtr outp, B.length message + 16)
+                        sealed <- B.packCStringLen (castPtr outp, B.length message + taglen)
                         mask <- B.packCStringLen (castPtr maskp, 16)
                         return (Just (sealed, mask))
                     else return Nothing
diff --git a/tests/NumberSpec.hs b/tests/NumberSpec.hs
--- a/tests/NumberSpec.hs
+++ b/tests/NumberSpec.hs
@@ -95,6 +95,24 @@
 bigPrime = 2 ^ (512 :: Int) - 569
 bigComposite = (2 ^ (256 :: Int) - 189) * (2 ^ (256 :: Int) - 357)
 
+-- | The two sizes at which the exponentiation hands its multiplication to
+-- s2n-bignum's assembly: a modulus of exactly sixteen or thirty-two 64-bit
+-- limbs, which is 1024 or 2048 bits -- the halves a CRT exponentiation works
+-- in for RSA-2048 and RSA-4096, and nothing else.  A property over moduli of
+-- no particular size reaches that path only by accident, and the one below
+-- with "a modulus a key would have" is 1025 bits, one limb too wide.
+modulus1024, modulus2048 :: Integer
+modulus1024 = bit 1023 .|. (bigPrime * bigComposite `mod` bit 1023) .|. 1
+modulus2048 =
+    bit 2047 .|. ((bigPrime * bigComposite) ^ (2 :: Int) `mod` bit 2047) .|. 1
+
+-- | A number of up to this many bytes.  'QAInteger' stops at thirty-two,
+-- which is too narrow for either of these: the base has to be able to fill a
+-- modulus and to overflow it, and the exponent's length is what the window
+-- walks.
+wideOf :: Int -> Gen Integer
+wideOf bytes = BE.os2ip <$> arbitraryBSof 0 bytes
+
 -- the index is threaded through so that repeated calls cannot be shared
 askAgain :: Int -> Integer -> Bool
 askAgain i n = i `seq` primalityTestMillerRabin 1 n
@@ -174,6 +192,16 @@
         \(QAInteger b) (QAInteger e) ->
             let m = 2 * bigPrime * bigComposite + 1 -- odd, and 1025 bits
              in expSafe b (abs e) m === expFast b (abs e) m
+    prop "agrees with the fast one at the two sizes with assembly behind them" $
+        forAll (elements [modulus1024, modulus2048]) $ \m ->
+            forAll (wideOf 300) $ \b ->
+                forAll (wideOf 256) $ \e ->
+                    expSafe b e m === expFast b e m
+    prop "agrees with the fast one whatever the exponent's length" $
+        forAll (choose (0, 129)) $ \bytes ->
+            forAll (wideOf bytes) $ \e ->
+                forAll (wideOf 128) $ \b ->
+                    expSafe b e modulus1024 === expFast b e modulus1024
   where
     safely (b, e, m) = expSafe b e m
     fastly (b, e, m) = expFast b e m
@@ -239,6 +267,10 @@
         numBytes i == byteCount i
     prop "num-bytes-small" $ \() ->
         map numBytes [0, 1, 255, 256, 257, 65535, 65536] == [0, 1, 1, 2, 2, 2, 3]
+    -- the magnitude, which is what GMP counts, and what the fallback used to
+    -- divide by 256 forever looking for a quotient of zero
+    prop "num-bits-negative" $ \(Positive i) ->
+        numBits (negate i) == numBits i
     prop "generate-param" $ \testDRG (Int1_2901 bits) ->
         let r = withTestDRG testDRG $ generateParams bits (Just SetHighest) False
          in r >= 0 && numBits r == bits && testBit r (bits - 1)
diff --git a/tests/StreamCipher/ChaChaPoly1305Spec.hs b/tests/StreamCipher/ChaChaPoly1305Spec.hs
--- a/tests/StreamCipher/ChaChaPoly1305Spec.hs
+++ b/tests/StreamCipher/ChaChaPoly1305Spec.hs
@@ -227,6 +227,12 @@
     it "refuses input shorter than the tag" $
         One.decrypt ctx nonce12 aad (B.replicate 8 0) 16
             `shouldBe` (Nothing :: Maybe B.ByteString)
+    it "refuses a ciphertext with no authentication tag" $
+        One.decrypt ctx nonce12 aad ciphertext 0
+            `shouldBe` (Nothing :: Maybe B.ByteString)
+    it "does not authenticate an altered ciphertext with a zero-length tag" $
+        One.decrypt ctx nonce12 aad (flipHead ciphertext) 0
+            `shouldBe` (Nothing :: Maybe B.ByteString)
     it "refuses a nonce that is not twelve bytes" $ do
         One.decrypt ctx (B.replicate 10 0) aad sealed 16
             `shouldBe` (Nothing :: Maybe B.ByteString)
