daemon: verify proof-of-work on every synced header; fork choice by work
DigiByte is multi-algorithm, so this brings in six hash functions: SHA256d and Scrypt in JS, and Qubit, Skein, Groestl and Odocrypt from DigiByte Core's own C sources compiled to WebAssembly (packages/p2p/native, emscripten via docker). Each header is checked against its nBits target and the network powLimit before it can enter the chain; a peer serving an invalid or future-dated header is benched. Competing branches are accepted only when they carry more accumulated work than what they replace. npm run pow:test -w @dgb-wallet/p2p verifies real mainnet headers of all six algorithms and that a tampered header fails.
This commit is contained in:
parent
0a5d7ade28
commit
93cd8b4bf4
39 changed files with 18469 additions and 168 deletions
|
|
@ -1,95 +1,111 @@
|
|||
# DigiByte.X Wallet — Security Roadmap
|
||||
|
||||
Derived from `D:\Dev\SilentCode\web_wallet_security_analysis.md` (the
|
||||
general web-wallet threat model) and mapped onto what this wallet
|
||||
actually does today. Each item says where we stand and what the next
|
||||
concrete step is. Ordered by the analysis' own priority: CSP first,
|
||||
then key-splitting, then hardware isolation.
|
||||
|
||||
Last reviewed: 2026-09-09.
|
||||
|
||||
---
|
||||
|
||||
## Where we stand against the threat model
|
||||
|
||||
| Threat (analysis §1–2) | Status | Notes |
|
||||
|---|---|---|
|
||||
| Custodial key control | ✅ N/A | Non-custodial. Seed never leaves the browser; only signed tx bytes go out. |
|
||||
| Server breach exposes keys | ✅ Mitigated | Nothing key-related on the server. Encrypted blobs live only in the user's `localStorage`. |
|
||||
| Phishing / typo-squat | ⚠️ Partial | `digibyte.x` is a BNS name with IP + TLS fingerprint on-chain, so wallet-aware clients pin the server. Plain browsers reaching us through `navigate.st` trust that gateway's TLS. |
|
||||
| XSS / injected script | ✅ Mitigated | Strict CSP live on `digibyte.x/web/` since 2026-09-06 (`script-src 'self'` + hash of the one inline script); asset tags carry SRI since 2026-09-09. |
|
||||
| Malicious extensions | ⚠️ Inherent | Nothing in-page can stop an extension with page access. Mitigation is the multi-sig item below. |
|
||||
| Local malware reading storage | ⚠️ Partial | Blobs are PBKDF2-210k + AES-GCM under the master password. Persistent PIN blob (100k rounds) weakens this for users who set a PIN — documented in `session-auth.ts`. |
|
||||
| DNS spoofing | ✅ Mitigated for pinned clients | On-chain fingerprint pinning; see `ops/nginx-digibyte-x.conf` header comment. |
|
||||
|
||||
## What the wallet already does (analysis §2 "Client-Side Architecture")
|
||||
|
||||
- **Local cryptography.** BIP39/BIP32 via `@dgb-wallet/core`; WebCrypto PBKDF2 + AES-GCM in `packages/keystore` and `packages/web-ui/src/session-auth.ts`.
|
||||
- **Encrypted local storage.** One master password per device; every wallet blob encrypted under it. Session auto-locks after 30 min idle. PIN is a shortcut with a 3-attempt budget; the master password restores it.
|
||||
- **Local signing.** PSBT built and signed in `SendScreen.tsx`; keys are derived on demand and dropped with the component.
|
||||
- **Verified broadcast.** `packages/p2p/src/broadcast.ts` treats a send as done only when an uninvolved peer announces the tx back (DGB Core drops policy failures silently). Fees sized to DGB's 100 sat/vB relay floor.
|
||||
- **Address hygiene (opt-in).** Settings → Security → "Fresh addresses" rotates receive and change addresses to the first unused index. Off by default because "used" is only complete with Blockbook enabled.
|
||||
|
||||
---
|
||||
|
||||
## Roadmap
|
||||
|
||||
### 1. Strict Content Security Policy — MANDATORY (analysis §3) — ✅ APPLIED 2026-09-06
|
||||
|
||||
Add to the nginx `location /web/` block on the VPS (and keep `ops/nginx-digibyte-x.conf` in sync):
|
||||
|
||||
```nginx
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-MYCXjyaeuO4n6g9JktOO1yXmG9rBTuGJ5Wk4GojDwig=' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://api.coingecko.com; img-src 'self' data:; base-uri 'self'; frame-ancestors 'none'; form-action 'none'; object-src 'none'" always;
|
||||
```
|
||||
|
||||
Notes:
|
||||
- The `sha256-…` value is the hash of the inline `<base>`-fixing script in the **built** `dist/index.html`. It changes whenever `packages/web-ui/index.html`'s inline script changes; recompute on each such change (a one-liner is in the deploy notes below) or move the script to a separate file under `assets/` to drop the hash entirely.
|
||||
- `base-uri 'self'` (not `'none'`): the inline script injects a `<base>` tag pointing at our own origin.
|
||||
- `connect-src` needs CoinGecko only while the price feed is opt-in enabled; everything else (`../p2p/`, `../blockbook/`) is same-origin.
|
||||
- `'unsafe-inline'` for styles is needed by a handful of inline `style=` attributes; removing them is a cleanup item, not a blocker.
|
||||
- The `navigate.st` gateway serves the same HTML under its own headers; CSP there is the gateway's to set.
|
||||
|
||||
Recompute the hash after a build:
|
||||
|
||||
```bash
|
||||
python -c "import re,hashlib,base64;h=open('packages/web-ui/dist/index.html',encoding='utf-8').read();s=re.findall(r'<script>(.*?)</script>',h,re.S)[0];print('sha256-'+base64.b64encode(hashlib.sha256(s.encode()).digest()).decode())"
|
||||
```
|
||||
|
||||
Applied and verified (zero violations through both digibyte.x and the navigate.st gateway). The repo mirror is `ops/nginx-digibyte-x.conf`; `ops/push.sh` warns when the live header's hash no longer matches the built inline script.
|
||||
|
||||
### 2. Subresource integrity + reproducible bundle — ✅ SRI done 2026-09-09
|
||||
|
||||
- ✅ `integrity="sha384-…"` + `crossorigin` on the `<script>`/`<link>` tags in `dist/index.html` at build time (`sri()` plugin in `packages/web-ui/vite.config.ts`), so a tampered asset file fails to load even if the HTML is intact.
|
||||
- Publish the bundle hash alongside each deploy (e.g. in the BNS record's `h` field or a signed `RELEASES.md`) so a user can compare what their browser loaded against what was released.
|
||||
|
||||
### 3. Drop the remaining inline script — ❌ NOT POSSIBLE as stated
|
||||
|
||||
The inline script must run before any relative URL is resolved, because the navigate.st gateway injects its own `<base href="/bns/digibyte.x/">` at the top of `<head>`; an external `./base-fix.js` would itself be resolved against that wrong base and never load. The script stays inline and hashed; `packages/web-ui/scripts/csp-hash.mjs` prints the hash and `ops/push.sh` checks it on every deploy, so the recompute step is automated instead of removed.
|
||||
|
||||
### 4. Multi-signature co-signing (analysis §4) — replaces "2FA"
|
||||
|
||||
DigiByte supports the same script system as Bitcoin, so a 2-of-2 (or 2-of-3 with a recovery key) P2WSH multisig is available today without smart contracts.
|
||||
|
||||
- `@dgb-wallet/core`: derive a second account for the co-signer and build BIP48-style (`m/48'/20'/0'/2'`) P2WSH multisig scripts; `@dgb-wallet/psbt` already handles PSBT, so add `witnessScript` inputs and partial-signature merging.
|
||||
- Second device = the `packages/mobile` app: it receives the PSBT (QR or the `/p2p/` daemon acting as a relay), shows outputs and amounts on its own screen, signs with Key B, returns the PSBT.
|
||||
- Browser finalizes when both signatures are present; broadcast path unchanged.
|
||||
- Recovery: the seed backup for each key plus the redeem script descriptor (`wsh(multi(2,…))`) — export it from Settings → Security → Wallet keys.
|
||||
|
||||
This is the item that neutralises the extension / XSS / local-malware residual risk: a compromised browser can leak Key A and still cannot move funds.
|
||||
|
||||
### 5. Hardware wallet bridge (analysis §5, "maximum protection")
|
||||
|
||||
WebUSB/WebHID to a Ledger or Trezor that carries DigiByte support. Keys never enter the page; the browser only assembles PSBTs. Same PSBT plumbing as item 4, so do it after multisig lands.
|
||||
|
||||
### 6. Browser-extension packaging (analysis §3)
|
||||
|
||||
Ship `packages/web-ui` as a Manifest V3 extension. Static code reviewed by the store, isolated origin, no gateway in the path. The runtime `<base>` fix and the `../p2p/` relative fetches already make the bundle origin-agnostic; the remaining work is the manifest, a fixed backend origin setting, and CSP in the manifest instead of nginx.
|
||||
|
||||
### 7. Smaller hardening items
|
||||
|
||||
- **PIN blob** lives in `localStorage` by design (user requirement: PIN survives reloads). Document it in-app (done, Settings → Security) and consider a device-bound key via WebAuthn PRF when browser support settles, so the blob is useless off-device.
|
||||
- **Master password change** re-encrypts all wallets and clears the PIN (done).
|
||||
- **Auto-lock** is 30 min idle; expose it as a setting.
|
||||
- **Clipboard**: the copy buttons put addresses on the clipboard; never the seed. Keep it that way.
|
||||
- **Blockbook exposure**: keep it opt-in; the Settings hint spells out that the indexer operator sees queried addresses.
|
||||
- **Rate limiting / error hygiene**: gateway text errors and indexer 429s must never look like "no funds". Handled in `p2p-fetch.ts` and the Blockbook client (parse-before-JSON, 429 backoff, small concurrency cap).
|
||||
# DigiByte.X Wallet — Security Roadmap
|
||||
|
||||
Derived from `D:\Dev\SilentCode\web_wallet_security_analysis.md` (the
|
||||
general web-wallet threat model) and mapped onto what this wallet
|
||||
actually does today. Each item says where we stand and what the next
|
||||
concrete step is. Ordered by the analysis' own priority: CSP first,
|
||||
then key-splitting, then hardware isolation.
|
||||
|
||||
Last reviewed: 2026-10-02.
|
||||
|
||||
---
|
||||
|
||||
## Where we stand against the threat model
|
||||
|
||||
| Threat (analysis §1–2) | Status | Notes |
|
||||
|---|---|---|
|
||||
| Custodial key control | ✅ N/A | Non-custodial. Seed never leaves the browser; only signed tx bytes go out. |
|
||||
| Server breach exposes keys | ✅ Mitigated | Nothing key-related on the server. Encrypted blobs live only in the user's `localStorage`. |
|
||||
| Phishing / typo-squat | ⚠️ Partial | `digibyte.x` is a BNS name with IP + TLS fingerprint on-chain, so wallet-aware clients pin the server. Plain browsers reaching us through `navigate.st` trust that gateway's TLS. |
|
||||
| XSS / injected script | ✅ Mitigated | Strict CSP live on `digibyte.x/web/` since 2026-09-06 (`script-src 'self'` + hash of the one inline script); asset tags carry SRI since 2026-09-09. |
|
||||
| Malicious extensions | ⚠️ Inherent | Nothing in-page can stop an extension with page access. Mitigation is the multi-sig item below. |
|
||||
| Local malware reading storage | ⚠️ Partial | Blobs are PBKDF2-210k + AES-GCM under the master password. Persistent PIN blob (100k rounds) weakens this for users who set a PIN — documented in `session-auth.ts`. |
|
||||
| DNS spoofing | ✅ Mitigated for pinned clients | On-chain fingerprint pinning; see `ops/nginx-digibyte-x.conf` header comment. |
|
||||
|
||||
## What the wallet already does (analysis §2 "Client-Side Architecture")
|
||||
|
||||
- **Local cryptography.** BIP39/BIP32 via `@dgb-wallet/core`; WebCrypto PBKDF2 + AES-GCM in `packages/keystore` and `packages/web-ui/src/session-auth.ts`.
|
||||
- **Encrypted local storage.** One master password per device; every wallet blob encrypted under it. Session auto-locks after 30 min idle. PIN is a shortcut with a 3-attempt budget; the master password restores it.
|
||||
- **Local signing.** PSBT built and signed in `SendScreen.tsx`; keys are derived on demand and dropped with the component.
|
||||
- **Verified broadcast.** `packages/p2p/src/broadcast.ts` treats a send as done only when an uninvolved peer announces the tx back (DGB Core drops policy failures silently). Fees sized to DGB's 100 sat/vB relay floor.
|
||||
- **Address hygiene (opt-in).** Settings → Security → "Fresh addresses" rotates receive and change addresses to the first unused index. Off by default because "used" is only complete with Blockbook enabled.
|
||||
|
||||
---
|
||||
|
||||
## Roadmap
|
||||
|
||||
### 1. Strict Content Security Policy — MANDATORY (analysis §3) — ✅ APPLIED 2026-09-06
|
||||
|
||||
Add to the nginx `location /web/` block on the VPS (and keep `ops/nginx-digibyte-x.conf` in sync):
|
||||
|
||||
```nginx
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-MYCXjyaeuO4n6g9JktOO1yXmG9rBTuGJ5Wk4GojDwig=' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://api.coingecko.com; img-src 'self' data:; base-uri 'self'; frame-ancestors 'none'; form-action 'none'; object-src 'none'" always;
|
||||
```
|
||||
|
||||
Notes:
|
||||
- The `sha256-…` value is the hash of the inline `<base>`-fixing script in the **built** `dist/index.html`. It changes whenever `packages/web-ui/index.html`'s inline script changes; recompute on each such change (a one-liner is in the deploy notes below) or move the script to a separate file under `assets/` to drop the hash entirely.
|
||||
- `base-uri 'self'` (not `'none'`): the inline script injects a `<base>` tag pointing at our own origin.
|
||||
- `connect-src` needs CoinGecko only while the price feed is opt-in enabled; everything else (`../p2p/`, `../blockbook/`) is same-origin.
|
||||
- `'unsafe-inline'` for styles is needed by a handful of inline `style=` attributes; removing them is a cleanup item, not a blocker.
|
||||
- The `navigate.st` gateway serves the same HTML under its own headers; CSP there is the gateway's to set.
|
||||
|
||||
Recompute the hash after a build:
|
||||
|
||||
```bash
|
||||
python -c "import re,hashlib,base64;h=open('packages/web-ui/dist/index.html',encoding='utf-8').read();s=re.findall(r'<script>(.*?)</script>',h,re.S)[0];print('sha256-'+base64.b64encode(hashlib.sha256(s.encode()).digest()).decode())"
|
||||
```
|
||||
|
||||
Applied and verified (zero violations through both digibyte.x and the navigate.st gateway). The repo mirror is `ops/nginx-digibyte-x.conf`; `ops/push.sh` warns when the live header's hash no longer matches the built inline script.
|
||||
|
||||
### 2. Subresource integrity + reproducible bundle — ✅ SRI done 2026-09-09
|
||||
|
||||
- ✅ `integrity="sha384-…"` + `crossorigin` on the `<script>`/`<link>` tags in `dist/index.html` at build time (`sri()` plugin in `packages/web-ui/vite.config.ts`), so a tampered asset file fails to load even if the HTML is intact.
|
||||
- Publish the bundle hash alongside each deploy (e.g. in the BNS record's `h` field or a signed `RELEASES.md`) so a user can compare what their browser loaded against what was released.
|
||||
|
||||
### 3. Drop the remaining inline script — ❌ NOT POSSIBLE as stated
|
||||
|
||||
The inline script must run before any relative URL is resolved, because the navigate.st gateway injects its own `<base href="/bns/digibyte.x/">` at the top of `<head>`; an external `./base-fix.js` would itself be resolved against that wrong base and never load. The script stays inline and hashed; `packages/web-ui/scripts/csp-hash.mjs` prints the hash and `ops/push.sh` checks it on every deploy, so the recompute step is automated instead of removed.
|
||||
|
||||
### 4. Multi-signature co-signing (analysis §4) — replaces "2FA"
|
||||
|
||||
DigiByte supports the same script system as Bitcoin, so a 2-of-2 (or 2-of-3 with a recovery key) P2WSH multisig is available today without smart contracts.
|
||||
|
||||
- `@dgb-wallet/core`: derive a second account for the co-signer and build BIP48-style (`m/48'/20'/0'/2'`) P2WSH multisig scripts; `@dgb-wallet/psbt` already handles PSBT, so add `witnessScript` inputs and partial-signature merging.
|
||||
- Second device = the `packages/mobile` app: it receives the PSBT (QR or the `/p2p/` daemon acting as a relay), shows outputs and amounts on its own screen, signs with Key B, returns the PSBT.
|
||||
- Browser finalizes when both signatures are present; broadcast path unchanged.
|
||||
- Recovery: the seed backup for each key plus the redeem script descriptor (`wsh(multi(2,…))`) — export it from Settings → Security → Wallet keys.
|
||||
|
||||
This is the item that neutralises the extension / XSS / local-malware residual risk: a compromised browser can leak Key A and still cannot move funds.
|
||||
|
||||
### 5. Hardware wallet bridge (analysis §5, "maximum protection")
|
||||
|
||||
WebUSB/WebHID to a Ledger or Trezor that carries DigiByte support. Keys never enter the page; the browser only assembles PSBTs. Same PSBT plumbing as item 4, so do it after multisig lands.
|
||||
|
||||
### 6. Browser-extension packaging (analysis §3)
|
||||
|
||||
Ship `packages/web-ui` as a Manifest V3 extension. Static code reviewed by the store, isolated origin, no gateway in the path. The runtime `<base>` fix and the `../p2p/` relative fetches already make the bundle origin-agnostic; the remaining work is the manifest, a fixed backend origin setting, and CSP in the manifest instead of nginx.
|
||||
|
||||
### 7. Smaller hardening items
|
||||
|
||||
- **PIN blob** lives in `localStorage` by design (user requirement: PIN survives reloads). Document it in-app (done, Settings → Security) and consider a device-bound key via WebAuthn PRF when browser support settles, so the blob is useless off-device.
|
||||
- **Master password change** re-encrypts all wallets and clears the PIN (done).
|
||||
- **Auto-lock** is 30 min idle; expose it as a setting.
|
||||
- **Clipboard**: the copy buttons put addresses on the clipboard; never the seed. Keep it that way.
|
||||
- **Blockbook exposure**: keep it opt-in; the Settings hint spells out that the indexer operator sees queried addresses.
|
||||
- **Rate limiting / error hygiene**: gateway text errors and indexer 429s must never look like "no funds". Handled in `p2p-fetch.ts` and the Blockbook client (parse-before-JSON, 429 backoff, small concurrency cap).
|
||||
|
||||
### 8. Header proof-of-work validation in the daemon — ✅ DONE 2026-10-02
|
||||
|
||||
Every header received during sync is hashed with the algorithm its version
|
||||
field names and checked against its nBits target and the network powLimit
|
||||
(Core's `CheckProofOfWork`). DigiByte is multi-algo, so this needed six hash
|
||||
functions: SHA256d and Scrypt in JS (`@noble/hashes`), and Qubit, Skein,
|
||||
Groestl and Odocrypt from DigiByte Core's own C sources compiled to
|
||||
WebAssembly (`packages/p2p/native`, built with emscripten in docker via
|
||||
`build.sh`). `packages/p2p/src/pow.ts` wraps it; `npm run pow:test -w
|
||||
@dgb-wallet/p2p` checks real mainnet headers of every algorithm and proves a
|
||||
tampered header fails. Fork choice is now by accumulated work, not header
|
||||
count, and a peer that serves an invalid or future-dated header is benched
|
||||
for six hours. Not implemented: per-algorithm difficulty retargeting
|
||||
(MultiShield) — unnecessary for a light client once work-weighted fork choice
|
||||
is in place, since a forged low-difficulty chain carries less work and loses.
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ push_daemon() {
|
|||
log "typechecking p2p"
|
||||
(cd packages/p2p && npx tsc --noEmit -p .)
|
||||
log "shipping daemon sources → $HOST:$REPO_DIR"
|
||||
tar -cz packages/p2p/src packages/p2p/bin packages/core/src packages/core/dist packages/core/package.json packages/p2p/package.json \
|
||||
tar -cz packages/p2p/src packages/p2p/bin packages/p2p/native/dgbpow.wasm packages/core/src packages/core/dist packages/core/package.json packages/p2p/package.json \
|
||||
| ssh "$HOST" "set -e
|
||||
tar -xz -C '$REPO_DIR'
|
||||
chown -R dgb-wallet:dgb-wallet '$REPO_DIR/packages/p2p' '$REPO_DIR/packages/core'
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ import {
|
|||
broadcastDandelion,
|
||||
scanWithPeers,
|
||||
crawlFilters,
|
||||
checkProofOfWork,
|
||||
workFromBits,
|
||||
loadPowWasm,
|
||||
NODE_COMPACT_FILTERS,
|
||||
NODE_NETWORK,
|
||||
NODE_NETWORK_LIMITED,
|
||||
|
|
@ -70,6 +73,12 @@ console.log(`[chain] disk-backed, tip ${chain.tipHeight.toLocaleString()} (adopt
|
|||
|
||||
let syncing = false;
|
||||
let syncRound = 0;
|
||||
// Peers that served an invalid (bad-PoW / future-dated) header. Skipped by
|
||||
// the sync rotation for a while; their connection is otherwise unaffected.
|
||||
const badPeers = new Map<string, number>();
|
||||
const BAD_PEER_MS = 6 * 60 * 60 * 1000;
|
||||
loadPowWasm();
|
||||
console.log('[chain] proof-of-work validation on (sha256d, scrypt, skein, qubit, odo, groestl)');
|
||||
// Header sync. Rotates through ready peers so no single peer decides
|
||||
// what our chain looks like, and handles forks: when a peer's batch does
|
||||
// not attach to our tip, find where it does attach, roll back to there
|
||||
|
|
@ -85,7 +94,8 @@ async function backgroundSync(): Promise<void> {
|
|||
// answer getheaders.) The advertised height is still used below as
|
||||
// a guard: a reorg is only accepted from a peer at least as high as
|
||||
// our tip.
|
||||
const ready = pool.pickReady();
|
||||
const now = Date.now();
|
||||
const ready = pool.pickReady().filter((p) => (badPeers.get(p.host) ?? 0) < now);
|
||||
const readyPeer = ready[syncRound++ % Math.max(1, ready.length)];
|
||||
if (!readyPeer) {
|
||||
syncing = false;
|
||||
|
|
@ -105,43 +115,98 @@ async function backgroundSync(): Promise<void> {
|
|||
// which is exactly how the daemon sat on a garbage branch for hours.
|
||||
let cursor: string | null = null; // last header hash of a fully-known batch, when walking up
|
||||
const ask = (locator: string[]) => readyPeer.send('getheaders', encodeGetHeaders(70019, locator));
|
||||
const onHeaders = (headers: BlockHeader[]) => {
|
||||
// Proof-of-work gate. Every header a peer sends is hashed with the
|
||||
// algorithm its version names and checked against its own target
|
||||
// (Core's CheckProofOfWork) before it can touch the chain. Invalid →
|
||||
// the batch is cut at the first bad header and the peer is benched.
|
||||
// Timestamps more than 2h in the future are rejected too.
|
||||
// Work is summed per batch so fork choice below is by accumulated
|
||||
// proof-of-work, not by header count.
|
||||
const validate = (hs: BlockHeader[]): { good: BlockHeader[]; bad?: { h: BlockHeader; reason: string } } => {
|
||||
const limit = Math.floor(Date.now() / 1000) + 2 * 60 * 60;
|
||||
for (let i = 0; i < hs.length; i++) {
|
||||
const h = hs[i];
|
||||
if (h.timestamp > limit) return { good: hs.slice(0, i), bad: { h, reason: 'timestamp too far in the future' } };
|
||||
const r = checkProofOfWork(h);
|
||||
if (!r.ok) return { good: hs.slice(0, i), bad: { h, reason: r.reason ?? 'bad pow' } };
|
||||
}
|
||||
return { good: hs };
|
||||
};
|
||||
const workOf = (hs: BlockHeader[]): bigint => hs.reduce((a, h) => a + workFromBits(h.bits), 0n);
|
||||
const workOfRange = (from: number, to: number): bigint => {
|
||||
let w = 0n;
|
||||
for (let h = from; h <= to; h++) { const x = chain.getByHeight(h); if (x) w += workFromBits(x.bits); }
|
||||
return w;
|
||||
};
|
||||
// A candidate competing branch being accumulated across batches until
|
||||
// its work beats what it would replace (or it ends and loses).
|
||||
let pendingBranch: { divergeH: number; headers: BlockHeader[]; droppedWork: bigint } | null = null;
|
||||
|
||||
const onHeaders = (headersRaw: BlockHeader[]) => {
|
||||
lastBatchAt = Date.now();
|
||||
const t0 = Date.now();
|
||||
if (headers.length === 0) { stalled = true; return; }
|
||||
let r = chain.append(headers);
|
||||
if (headersRaw.length === 0) { stalled = true; return; }
|
||||
const v = validate(headersRaw);
|
||||
if (v.bad) {
|
||||
console.log(`[chain] ${readyPeer.host} sent an INVALID header at ${v.bad.h.hash.slice(0, 16)}… (${v.bad.reason}) — benching peer, keeping ${v.good.length} valid header(s) before it`);
|
||||
badPeers.set(readyPeer.host, Date.now() + BAD_PEER_MS);
|
||||
if (v.good.length === 0) { stalled = true; return; }
|
||||
}
|
||||
const headers = v.good;
|
||||
const vMs = Date.now() - t0;
|
||||
|
||||
// Continuing a candidate branch from a previous batch?
|
||||
if (pendingBranch && headers[0].prevBlock === pendingBranch.headers[pendingBranch.headers.length - 1].hash) {
|
||||
pendingBranch.headers.push(...headers);
|
||||
} else if (pendingBranch) {
|
||||
pendingBranch = null; // peer changed subject; drop the candidate
|
||||
}
|
||||
|
||||
let r = pendingBranch ? { appended: 0, rejectedAt: headers[0], reason: 'candidate' } : chain.append(headers);
|
||||
if (r.rejectedAt && r.appended === 0) {
|
||||
const forkH = chain.findHeight(headers[0].prevBlock);
|
||||
if (forkH < 0) {
|
||||
console.log(`[chain] batch from ${readyPeer.host} rejected: ${r.reason?.slice(0, 100)} (fork point not in our chain — next peer)`);
|
||||
let divergeH: number;
|
||||
let branch: BlockHeader[];
|
||||
if (pendingBranch) {
|
||||
divergeH = pendingBranch.divergeH; branch = pendingBranch.headers;
|
||||
} else {
|
||||
const forkH = chain.findHeight(headers[0].prevBlock);
|
||||
if (forkH < 0) {
|
||||
console.log(`[chain] batch from ${readyPeer.host} rejected: ${r.reason?.slice(0, 100)} (fork point not in our chain — next peer)`);
|
||||
stalled = true; return;
|
||||
}
|
||||
// How much of the batch do we already have on our branch?
|
||||
let known = 0;
|
||||
while (known < headers.length && chain.getByHeight(forkH + 1 + known)?.hash === headers[known].hash) known++;
|
||||
if (known === headers.length) {
|
||||
// Entirely known: keep walking up the peer's chain from here.
|
||||
cursor = headers[headers.length - 1].hash;
|
||||
const nextH = forkH + known;
|
||||
if (nextH >= chain.tipHeight) { stalled = true; return; } // peer is behind us
|
||||
ask([cursor, DGB_GENESIS_HASH]);
|
||||
return;
|
||||
}
|
||||
divergeH = forkH + known;
|
||||
branch = headers.slice(known);
|
||||
pendingBranch = { divergeH, headers: branch, droppedWork: workOfRange(divergeH + 1, chain.tipHeight) };
|
||||
}
|
||||
const depth = chain.tipHeight - divergeH;
|
||||
const branchWork = workOf(branch);
|
||||
const dropped = pendingBranch!.droppedWork;
|
||||
if (branchWork <= dropped) {
|
||||
if (headersRaw.length >= 2000 && !v.bad) {
|
||||
// Branch may continue — ask for more before judging.
|
||||
cursor = branch[branch.length - 1].hash;
|
||||
ask([cursor, DGB_GENESIS_HASH]);
|
||||
return;
|
||||
}
|
||||
console.log(`[chain] ${readyPeer.host} offered a ${branch.length}-header branch at ${divergeH.toLocaleString()} with less work than our ${depth.toLocaleString()}-deep tip (${(Number(branchWork * 1000n / (dropped || 1n)) / 10).toFixed(1)}%) — ignored`);
|
||||
pendingBranch = null;
|
||||
stalled = true; return;
|
||||
}
|
||||
// How much of the batch do we already have on our branch?
|
||||
let known = 0;
|
||||
while (known < headers.length && chain.getByHeight(forkH + 1 + known)?.hash === headers[known].hash) known++;
|
||||
if (known === headers.length) {
|
||||
// Entirely known: keep walking up the peer's chain from here.
|
||||
cursor = headers[headers.length - 1].hash;
|
||||
const nextH = forkH + known;
|
||||
if (nextH >= chain.tipHeight) { stalled = true; return; } // peer is behind us
|
||||
ask([cursor, DGB_GENESIS_HASH]);
|
||||
return;
|
||||
}
|
||||
const divergeH = forkH + known; // last common height
|
||||
const depth = chain.tipHeight - divergeH; // what we would drop
|
||||
const branch = headers.length - known; // what the peer showed us so far
|
||||
const peerHeight = readyPeer.info?.startHeight ?? 0;
|
||||
if (peerHeight < chain.tipHeight) {
|
||||
console.log(`[chain] ${readyPeer.host} (adv. height ${peerHeight.toLocaleString()}) offered a branch at ${divergeH.toLocaleString()} against our ${depth.toLocaleString()}-deep tip ${chain.tipHeight.toLocaleString()} — ignored (lower than us)`);
|
||||
stalled = true; return;
|
||||
}
|
||||
if (branch < depth && branch < 2000) {
|
||||
console.log(`[chain] ${readyPeer.host} offered a ${branch}-header branch at ${divergeH.toLocaleString()} against our ${depth.toLocaleString()}-deep tip — ignored (too short)`);
|
||||
stalled = true; return;
|
||||
}
|
||||
console.log(`[chain] REORG via ${readyPeer.host} (adv. height ${peerHeight.toLocaleString()}): our tip ${chain.tipHeight.toLocaleString()} is off the network chain; rolling back ${depth.toLocaleString()} headers to ${divergeH.toLocaleString()} (${Date.now() - t0}ms to locate)`);
|
||||
console.log(`[chain] REORG via ${readyPeer.host}: a branch from ${divergeH.toLocaleString()} carries more work than our tip ${chain.tipHeight.toLocaleString()} (+${((Number(branchWork * 1000n / (dropped || 1n)) / 10) - 100).toFixed(1)}%); rolling back ${depth.toLocaleString()} headers, applying ${branch.length} (validated, ${vMs}ms)`);
|
||||
chain.rollbackTo(divergeH);
|
||||
r = chain.append(headers.slice(known));
|
||||
r = chain.append(branch);
|
||||
pendingBranch = null;
|
||||
if (chain.tipHeight < before) {
|
||||
let forgot = 0;
|
||||
for (const [k, rs] of lastScan) if (rs.endHeight > chain.tipHeight) { lastScan.delete(k); forgot++; }
|
||||
|
|
@ -152,9 +217,10 @@ async function backgroundSync(): Promise<void> {
|
|||
console.log(`[chain] batch from ${readyPeer.host} partially applied (+${r.appended}): ${r.reason?.slice(0, 120)}`);
|
||||
}
|
||||
cursor = null;
|
||||
if (v.bad) { stalled = true; return; } // don't ask a benched peer for more
|
||||
// DGB peers answer with up to 2000 headers (some send more); a short
|
||||
// batch means we are at their tip.
|
||||
if (headers.length >= 2000) ask(chain.buildLocator());
|
||||
if (headersRaw.length >= 2000) ask(chain.buildLocator());
|
||||
else stalled = true;
|
||||
};
|
||||
readyPeer.on('headers', onHeaders as never);
|
||||
|
|
|
|||
26
packages/p2p/native/build.sh
Normal file
26
packages/p2p/native/build.sh
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
# Build dgbpow.wasm from DigiByte Core's hash sources with emscripten in
|
||||
# docker (no local toolchain needed). Output: packages/p2p/native/dgbpow.wasm
|
||||
# which the daemon loads at startup (src/pow.ts).
|
||||
#
|
||||
# bash packages/p2p/native/build.sh
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
IMG="${EMSDK_IMAGE:-emscripten/emsdk:3.1.61}"
|
||||
|
||||
# Git Bash on Windows mangles "/src" style args; MSYS_NO_PATHCONV keeps
|
||||
# the container paths intact.
|
||||
MSYS_NO_PATHCONV=1 docker run --rm -v "$here":/work -w /work "$IMG" bash -c '
|
||||
set -e
|
||||
emcc -O3 -DNDEBUG -fno-exceptions -fno-rtti \
|
||||
-s STANDALONE_WASM=1 -s PURE_WASI=0 --no-entry \
|
||||
-s EXPORTED_FUNCTIONS=_in_ptr,_out_ptr,_hash_qubit,_hash_skein512,_hash_groestl512,_hash_odo \
|
||||
-s INITIAL_MEMORY=1048576 -s ALLOW_MEMORY_GROWTH=0 -s STACK_SIZE=262144 \
|
||||
-Isrc \
|
||||
dgbpow.c odo_glue.cpp \
|
||||
src/luffa.cpp src/cubehash.cpp src/shavite.cpp src/simd.cpp src/echo.cpp \
|
||||
src/skein.cpp src/groestl.cpp src/odocrypt.cpp src/KeccakP-800-reference.cpp \
|
||||
-o dgbpow.wasm
|
||||
ls -la dgbpow.wasm
|
||||
'
|
||||
echo "built: $here/dgbpow.wasm"
|
||||
73
packages/p2p/native/dgbpow.c
Normal file
73
packages/p2p/native/dgbpow.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// DigiByte multi-algo proof-of-work hashes, compiled to WebAssembly.
|
||||
//
|
||||
// Thin C wrapper over DigiByte Core's own implementations (src/crypto in
|
||||
// DigiByte-Core/digibyte, copied verbatim into ./src): sphlib Luffa,
|
||||
// CubeHash, SHAvite, SIMD, Echo, Skein, Groestl, plus Odocrypt and its
|
||||
// Keccak-p[800] permutation. SHA256d and Scrypt are done in JS
|
||||
// (@noble/hashes) and are not here.
|
||||
//
|
||||
// Interface is deliberately pointer-free for the caller: fixed static
|
||||
// buffers, the JS side copies 80 bytes in, calls one function, copies the
|
||||
// digest out. No malloc, no libc I/O, no imports.
|
||||
//
|
||||
// in_ptr() → address of the 80-byte header buffer
|
||||
// out_ptr() → address of the 64-byte output buffer
|
||||
// hash_qubit() → 32 bytes written to out (Luffa→CubeHash→SHAvite→SIMD→Echo, trim 256)
|
||||
// hash_skein512() → 64 bytes written to out (caller SHA256s them: Core's HashSkein)
|
||||
// hash_groestl512() → 64 bytes written to out (caller SHA256s them: Core's HashGroestl)
|
||||
// hash_odo(key) → 32 bytes written to out (OdoCrypt(key) + Keccak-p[800,12], per hashodo.h)
|
||||
//
|
||||
// Build: see build.sh (emscripten in docker).
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "src/sph_luffa.h"
|
||||
#include "src/sph_cubehash.h"
|
||||
#include "src/sph_shavite.h"
|
||||
#include "src/sph_simd.h"
|
||||
#include "src/sph_echo.h"
|
||||
#include "src/sph_skein.h"
|
||||
#include "src/sph_groestl.h"
|
||||
|
||||
#define EXPORT __attribute__((used, visibility("default")))
|
||||
|
||||
static unsigned char g_in[80];
|
||||
static unsigned char g_out[64];
|
||||
|
||||
EXPORT unsigned char* in_ptr(void) { return g_in; }
|
||||
EXPORT unsigned char* out_ptr(void) { return g_out; }
|
||||
|
||||
EXPORT void hash_qubit(void) {
|
||||
unsigned char h[64];
|
||||
sph_luffa512_context luffa; sph_cubehash512_context cube; sph_shavite512_context shavite;
|
||||
sph_simd512_context simd; sph_echo512_context echo;
|
||||
sph_luffa512_init(&luffa); sph_luffa512(&luffa, g_in, 80); sph_luffa512_close(&luffa, h);
|
||||
sph_cubehash512_init(&cube); sph_cubehash512(&cube, h, 64); sph_cubehash512_close(&cube, h);
|
||||
sph_shavite512_init(&shavite); sph_shavite512(&shavite, h, 64); sph_shavite512_close(&shavite, h);
|
||||
sph_simd512_init(&simd); sph_simd512(&simd, h, 64); sph_simd512_close(&simd, h);
|
||||
sph_echo512_init(&echo); sph_echo512(&echo, h, 64); sph_echo512_close(&echo, h);
|
||||
memcpy(g_out, h, 32);
|
||||
}
|
||||
|
||||
EXPORT void hash_skein512(void) {
|
||||
sph_skein512_context c;
|
||||
sph_skein512_init(&c); sph_skein512(&c, g_in, 80); sph_skein512_close(&c, g_out);
|
||||
}
|
||||
|
||||
EXPORT void hash_groestl512(void) {
|
||||
sph_groestl512_context c;
|
||||
sph_groestl512_init(&c); sph_groestl512(&c, g_in, 80); sph_groestl512_close(&c, g_out);
|
||||
}
|
||||
|
||||
// Implemented in odo_glue.cpp (OdoCrypt and the Keccak permutation are
|
||||
// C++ in Core's tree): OdoCrypt(key).Encrypt + KeccakP800_Permute_12rounds
|
||||
// over a 100-byte state, per hashodo.h.
|
||||
void odo_hash(uint32_t key, char* state100);
|
||||
|
||||
EXPORT void hash_odo(uint32_t key) {
|
||||
char cipher[100];
|
||||
memset(cipher, 0, sizeof cipher);
|
||||
memcpy(cipher, g_in, 80);
|
||||
cipher[80] = 1;
|
||||
odo_hash(key, cipher);
|
||||
memcpy(g_out, cipher, 32);
|
||||
}
|
||||
BIN
packages/p2p/native/dgbpow.wasm
Normal file
BIN
packages/p2p/native/dgbpow.wasm
Normal file
Binary file not shown.
9
packages/p2p/native/odo_glue.cpp
Normal file
9
packages/p2p/native/odo_glue.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// C-callable shim around DigiByte Core's OdoCrypt class and the Keccak-p[800]
|
||||
// permutation (both C++ in Core's src/crypto). Mirrors hashodo.h.
|
||||
#include "src/odocrypt.h"
|
||||
#include "src/KeccakP-800-SnP.h"
|
||||
|
||||
extern "C" void odo_hash(uint32_t key, char* state100) {
|
||||
OdoCrypt(key).Encrypt(state100, state100);
|
||||
KeccakP800_Permute_12rounds(state100);
|
||||
}
|
||||
41
packages/p2p/native/src/KeccakP-800-SnP.h
Normal file
41
packages/p2p/native/src/KeccakP-800-SnP.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
To the extent possible under law, the implementer has waived all copyright
|
||||
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
||||
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
||||
denoted as "the implementer".
|
||||
|
||||
For more information, feedback or questions, please refer to our websites:
|
||||
http://keccak.noekeon.org/
|
||||
http://keyak.noekeon.org/
|
||||
http://ketje.noekeon.org/
|
||||
|
||||
and related or neighboring rights to the source code in this file.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#ifndef _KeccakP_800_SnP_h_
|
||||
#define _KeccakP_800_SnP_h_
|
||||
|
||||
/** For the documentation, see SnP-documentation.h.
|
||||
*/
|
||||
|
||||
#define KeccakP800_implementation "32-bit reference implementation"
|
||||
#define KeccakP800_stateSizeInBytes 100
|
||||
#define KeccakP800_stateAlignment 4
|
||||
|
||||
#ifdef KeccakReference
|
||||
void KeccakP800_StaticInitialize( void );
|
||||
#else
|
||||
#define KeccakP800_StaticInitialize()
|
||||
#endif
|
||||
void KeccakP800_Initialize(void *state);
|
||||
void KeccakP800_AddByte(void *state, unsigned char data, unsigned int offset);
|
||||
void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount);
|
||||
void KeccakP800_Permute_12rounds(void *state);
|
||||
void KeccakP800_Permute_22rounds(void *state);
|
||||
void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
|
||||
|
||||
#endif
|
||||
422
packages/p2p/native/src/KeccakP-800-reference.cpp
Normal file
422
packages/p2p/native/src/KeccakP-800-reference.cpp
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
/*
|
||||
To the extent possible under law, the implementer has waived all copyright
|
||||
|
||||
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
|
||||
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
|
||||
hereby denoted as "the implementer".
|
||||
|
||||
For more information, feedback or questions, please refer to our website:
|
||||
https://keccak.team/
|
||||
|
||||
and related or neighboring rights to the source code in this file.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
---
|
||||
|
||||
This file implements Keccak-p[800] in a SnP-compatible way.
|
||||
Please refer to SnP-documentation.h for more details.
|
||||
|
||||
This implementation comes with KeccakP-800-SnP.h in the same folder.
|
||||
Please refer to LowLevel.build for the exact list of other files it must be combined with.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "brg_endian.h"
|
||||
#ifdef KeccakReference
|
||||
#include "displayIntermediateValues.h"
|
||||
#endif
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned int UINT32;
|
||||
typedef UINT32 tKeccakLane;
|
||||
|
||||
#define maxNrRounds 22
|
||||
#define nrLanes 25
|
||||
#define index(x, y) (((x)%5)+5*((y)%5))
|
||||
|
||||
#ifdef KeccakReference
|
||||
|
||||
static tKeccakLane KeccakRoundConstants[maxNrRounds];
|
||||
static unsigned int KeccakRhoOffsets[nrLanes];
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_InitializeRoundConstants(void);
|
||||
void KeccakP800_InitializeRhoOffsets(void);
|
||||
static int LFSR86540(UINT8 *LFSR);
|
||||
|
||||
void KeccakP800_StaticInitialize(void)
|
||||
{
|
||||
if (sizeof(tKeccakLane) != 4) {
|
||||
printf("tKeccakLane should be 32-bit wide\n");
|
||||
abort();
|
||||
}
|
||||
KeccakP800_InitializeRoundConstants();
|
||||
KeccakP800_InitializeRhoOffsets();
|
||||
}
|
||||
|
||||
void KeccakP800_InitializeRoundConstants(void)
|
||||
{
|
||||
UINT8 LFSRstate = 0x01;
|
||||
unsigned int i, j, bitPosition;
|
||||
|
||||
for(i=0; i<maxNrRounds; i++) {
|
||||
KeccakRoundConstants[i] = 0;
|
||||
for(j=0; j<7; j++) {
|
||||
bitPosition = (1<<j)-1; /* 2^j-1 */
|
||||
if (LFSR86540(&LFSRstate) && (bitPosition < (sizeof(tKeccakLane)*8)))
|
||||
KeccakRoundConstants[i] ^= (tKeccakLane)(1<<bitPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeccakP800_InitializeRhoOffsets(void)
|
||||
{
|
||||
unsigned int x, y, t, newX, newY;
|
||||
|
||||
KeccakRhoOffsets[index(0, 0)] = 0;
|
||||
x = 1;
|
||||
y = 0;
|
||||
for(t=0; t<24; t++) {
|
||||
KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % (sizeof(tKeccakLane) * 8);
|
||||
newX = (0*x+1*y) % 5;
|
||||
newY = (2*x+3*y) % 5;
|
||||
x = newX;
|
||||
y = newY;
|
||||
}
|
||||
}
|
||||
|
||||
static int LFSR86540(UINT8 *LFSR)
|
||||
{
|
||||
int result = ((*LFSR) & 0x01) != 0;
|
||||
if (((*LFSR) & 0x80) != 0)
|
||||
/* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */
|
||||
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
|
||||
else
|
||||
(*LFSR) <<= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const tKeccakLane KeccakRoundConstants[maxNrRounds] =
|
||||
{
|
||||
0x00000001,
|
||||
0x00008082,
|
||||
0x0000808a,
|
||||
0x80008000,
|
||||
0x0000808b,
|
||||
0x80000001,
|
||||
0x80008081,
|
||||
0x00008009,
|
||||
0x0000008a,
|
||||
0x00000088,
|
||||
0x80008009,
|
||||
0x8000000a,
|
||||
0x8000808b,
|
||||
0x0000008b,
|
||||
0x00008089,
|
||||
0x00008003,
|
||||
0x00008002,
|
||||
0x00000080,
|
||||
0x0000800a,
|
||||
0x8000000a,
|
||||
0x80008081,
|
||||
0x00008080,
|
||||
};
|
||||
|
||||
static const unsigned int KeccakRhoOffsets[nrLanes] =
|
||||
{
|
||||
0, 1, 30, 28, 27, 4, 12, 6, 23, 20, 3, 10, 11, 25, 7, 9, 13, 15, 21, 8, 18, 2, 29, 24, 14
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_Initialize(void *state)
|
||||
{
|
||||
memset(state, 0, 800/8);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_AddByte(void *state, unsigned char byte, unsigned int offset)
|
||||
{
|
||||
assert(offset < 100);
|
||||
((unsigned char *)state)[offset] ^= byte;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
for(i=0; i<length; i++)
|
||||
((unsigned char *)state)[offset+i] ^= data[i];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
memcpy((unsigned char*)state+offset, data, length);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount)
|
||||
{
|
||||
assert(byteCount <= 100);
|
||||
memset(state, 0, byteCount);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state);
|
||||
static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords);
|
||||
void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds);
|
||||
void KeccakP800Round(tKeccakLane *state, unsigned int indexRound);
|
||||
static void theta(tKeccakLane *A);
|
||||
static void rho(tKeccakLane *A);
|
||||
static void pi(tKeccakLane *A);
|
||||
static void chi(tKeccakLane *A);
|
||||
static void iota(tKeccakLane *A, unsigned int indexRound);
|
||||
|
||||
void KeccakP800_Permute_Nrounds(void *state, unsigned int nrounds)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, nrounds);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, nrounds);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeccakP800_Permute_12rounds(void *state)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, 12);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, 12);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeccakP800_Permute_22rounds(void *state)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, 22);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, 22);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for(i=0; i<nrLanes; i++) {
|
||||
stateAsWords[i] = 0;
|
||||
for(j=0; j<sizeof(tKeccakLane); j++)
|
||||
stateAsWords[i] |= (tKeccakLane)(state[i*sizeof(tKeccakLane)+j]) << (8*j);
|
||||
}
|
||||
}
|
||||
|
||||
static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for(i=0; i<nrLanes; i++)
|
||||
for(j=0; j<sizeof(tKeccakLane); j++)
|
||||
state[i*sizeof(tKeccakLane)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
|
||||
}
|
||||
|
||||
void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "Same, with lanes as 32-bit words", state, 800);
|
||||
#endif
|
||||
|
||||
for(i=(maxNrRounds-nrRounds); i<maxNrRounds; i++)
|
||||
KeccakP800Round(state, i);
|
||||
}
|
||||
|
||||
void KeccakP800Round(tKeccakLane *state, unsigned int indexRound)
|
||||
{
|
||||
#ifdef KeccakReference
|
||||
displayRoundNumber(3, indexRound);
|
||||
#endif
|
||||
|
||||
theta(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After theta", state, 800);
|
||||
#endif
|
||||
|
||||
rho(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After rho", state, 800);
|
||||
#endif
|
||||
|
||||
pi(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After pi", state, 800);
|
||||
#endif
|
||||
|
||||
chi(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After chi", state, 800);
|
||||
#endif
|
||||
|
||||
iota(state, indexRound);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After iota", state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROL32(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (sizeof(tKeccakLane)*8-offset))) : a)
|
||||
|
||||
static void theta(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane C[5], D[5];
|
||||
|
||||
for(x=0; x<5; x++) {
|
||||
C[x] = 0;
|
||||
for(y=0; y<5; y++)
|
||||
C[x] ^= A[index(x, y)];
|
||||
}
|
||||
for(x=0; x<5; x++)
|
||||
D[x] = ROL32(C[(x+1)%5], 1) ^ C[(x+4)%5];
|
||||
for(x=0; x<5; x++)
|
||||
for(y=0; y<5; y++)
|
||||
A[index(x, y)] ^= D[x];
|
||||
}
|
||||
|
||||
static void rho(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
A[index(x, y)] = ROL32(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
|
||||
}
|
||||
|
||||
static void pi(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane tempA[25];
|
||||
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
tempA[index(x, y)] = A[index(x, y)];
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
|
||||
}
|
||||
|
||||
static void chi(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane C[5];
|
||||
|
||||
for(y=0; y<5; y++) {
|
||||
for(x=0; x<5; x++)
|
||||
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
|
||||
for(x=0; x<5; x++)
|
||||
A[index(x, y)] = C[x];
|
||||
}
|
||||
}
|
||||
|
||||
static void iota(tKeccakLane *A, unsigned int indexRound)
|
||||
{
|
||||
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
memcpy(data, (unsigned char*)state+offset, length);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
for(i=0; i<length; i++)
|
||||
output[i] = input[i] ^ ((unsigned char *)state)[offset+i];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_DisplayRoundConstants(FILE *f)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i<maxNrRounds; i++) {
|
||||
fprintf(f, "RC[%02i][0][0] = ", i);
|
||||
fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i]));
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void KeccakP800_DisplayRhoOffsets(FILE *f)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
for(y=0; y<5; y++) for(x=0; x<5; x++) {
|
||||
fprintf(f, "RhoOffset[%i][%i] = ", x, y);
|
||||
fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
393
packages/p2p/native/src/aes_helper.h
Normal file
393
packages/p2p/native/src/aes_helper.h
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* $Id: aes_helper.c 220 2010-06-09 09:21:50Z tp $
|
||||
*/
|
||||
/*
|
||||
* AES tables. This file is not meant to be compiled by itself; it
|
||||
* is included by some hash function implementations. It contains
|
||||
* the precomputed tables and helper macros for evaluating an AES
|
||||
* round, optionally with a final XOR with a subkey.
|
||||
*
|
||||
* By default, this file defines the tables and macros for little-endian
|
||||
* processing (i.e. it is assumed that the input bytes have been read
|
||||
* from memory and assembled with the little-endian convention). If
|
||||
* the 'AES_BIG_ENDIAN' macro is defined (to a non-zero integer value)
|
||||
* when this file is included, then the tables and macros for big-endian
|
||||
* processing are defined instead. The big-endian tables and macros have
|
||||
* names distinct from the little-endian tables and macros, hence it is
|
||||
* possible to have both simultaneously, by including this file twice
|
||||
* (with and without the AES_BIG_ENDIAN macro).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include "sph_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
#if AES_BIG_ENDIAN
|
||||
|
||||
#define AESx(x) ( ((SPH_C32(x) >> 24) & SPH_C32(0x000000FF)) \
|
||||
| ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \
|
||||
| ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \
|
||||
| ((SPH_C32(x) << 24) & SPH_C32(0xFF000000)))
|
||||
|
||||
#define AES0 AES0_BE
|
||||
#define AES1 AES1_BE
|
||||
#define AES2 AES2_BE
|
||||
#define AES3 AES3_BE
|
||||
|
||||
#define AES_ROUND_BE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[((X0) >> 24) & 0xFF] \
|
||||
^ AES1[((X1) >> 16) & 0xFF] \
|
||||
^ AES2[((X2) >> 8) & 0xFF] \
|
||||
^ AES3[(X3) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[((X1) >> 24) & 0xFF] \
|
||||
^ AES1[((X2) >> 16) & 0xFF] \
|
||||
^ AES2[((X3) >> 8) & 0xFF] \
|
||||
^ AES3[(X0) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[((X2) >> 24) & 0xFF] \
|
||||
^ AES1[((X3) >> 16) & 0xFF] \
|
||||
^ AES2[((X0) >> 8) & 0xFF] \
|
||||
^ AES3[(X1) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[((X3) >> 24) & 0xFF] \
|
||||
^ AES1[((X0) >> 16) & 0xFF] \
|
||||
^ AES2[((X1) >> 8) & 0xFF] \
|
||||
^ AES3[(X2) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_BE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_BE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#else
|
||||
|
||||
#define AESx(x) SPH_C32(x)
|
||||
#define AES0 AES0_LE
|
||||
#define AES1 AES1_LE
|
||||
#define AES2 AES2_LE
|
||||
#define AES3 AES3_LE
|
||||
|
||||
#define AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[(X0) & 0xFF] \
|
||||
^ AES1[((X1) >> 8) & 0xFF] \
|
||||
^ AES2[((X2) >> 16) & 0xFF] \
|
||||
^ AES3[((X3) >> 24) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[(X1) & 0xFF] \
|
||||
^ AES1[((X2) >> 8) & 0xFF] \
|
||||
^ AES2[((X3) >> 16) & 0xFF] \
|
||||
^ AES3[((X0) >> 24) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[(X2) & 0xFF] \
|
||||
^ AES1[((X3) >> 8) & 0xFF] \
|
||||
^ AES2[((X0) >> 16) & 0xFF] \
|
||||
^ AES3[((X1) >> 24) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[(X3) & 0xFF] \
|
||||
^ AES1[((X0) >> 8) & 0xFF] \
|
||||
^ AES2[((X1) >> 16) & 0xFF] \
|
||||
^ AES3[((X2) >> 24) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_LE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_LE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The AES*[] tables allow us to perform a fast evaluation of an AES
|
||||
* round; table AESi[] combines SubBytes for a byte at row i, and
|
||||
* MixColumns for the column where that byte goes after ShiftRows.
|
||||
*/
|
||||
|
||||
static const sph_u32 AES0[256] = {
|
||||
AESx(0xA56363C6), AESx(0x847C7CF8), AESx(0x997777EE), AESx(0x8D7B7BF6),
|
||||
AESx(0x0DF2F2FF), AESx(0xBD6B6BD6), AESx(0xB16F6FDE), AESx(0x54C5C591),
|
||||
AESx(0x50303060), AESx(0x03010102), AESx(0xA96767CE), AESx(0x7D2B2B56),
|
||||
AESx(0x19FEFEE7), AESx(0x62D7D7B5), AESx(0xE6ABAB4D), AESx(0x9A7676EC),
|
||||
AESx(0x45CACA8F), AESx(0x9D82821F), AESx(0x40C9C989), AESx(0x877D7DFA),
|
||||
AESx(0x15FAFAEF), AESx(0xEB5959B2), AESx(0xC947478E), AESx(0x0BF0F0FB),
|
||||
AESx(0xECADAD41), AESx(0x67D4D4B3), AESx(0xFDA2A25F), AESx(0xEAAFAF45),
|
||||
AESx(0xBF9C9C23), AESx(0xF7A4A453), AESx(0x967272E4), AESx(0x5BC0C09B),
|
||||
AESx(0xC2B7B775), AESx(0x1CFDFDE1), AESx(0xAE93933D), AESx(0x6A26264C),
|
||||
AESx(0x5A36366C), AESx(0x413F3F7E), AESx(0x02F7F7F5), AESx(0x4FCCCC83),
|
||||
AESx(0x5C343468), AESx(0xF4A5A551), AESx(0x34E5E5D1), AESx(0x08F1F1F9),
|
||||
AESx(0x937171E2), AESx(0x73D8D8AB), AESx(0x53313162), AESx(0x3F15152A),
|
||||
AESx(0x0C040408), AESx(0x52C7C795), AESx(0x65232346), AESx(0x5EC3C39D),
|
||||
AESx(0x28181830), AESx(0xA1969637), AESx(0x0F05050A), AESx(0xB59A9A2F),
|
||||
AESx(0x0907070E), AESx(0x36121224), AESx(0x9B80801B), AESx(0x3DE2E2DF),
|
||||
AESx(0x26EBEBCD), AESx(0x6927274E), AESx(0xCDB2B27F), AESx(0x9F7575EA),
|
||||
AESx(0x1B090912), AESx(0x9E83831D), AESx(0x742C2C58), AESx(0x2E1A1A34),
|
||||
AESx(0x2D1B1B36), AESx(0xB26E6EDC), AESx(0xEE5A5AB4), AESx(0xFBA0A05B),
|
||||
AESx(0xF65252A4), AESx(0x4D3B3B76), AESx(0x61D6D6B7), AESx(0xCEB3B37D),
|
||||
AESx(0x7B292952), AESx(0x3EE3E3DD), AESx(0x712F2F5E), AESx(0x97848413),
|
||||
AESx(0xF55353A6), AESx(0x68D1D1B9), AESx(0x00000000), AESx(0x2CEDEDC1),
|
||||
AESx(0x60202040), AESx(0x1FFCFCE3), AESx(0xC8B1B179), AESx(0xED5B5BB6),
|
||||
AESx(0xBE6A6AD4), AESx(0x46CBCB8D), AESx(0xD9BEBE67), AESx(0x4B393972),
|
||||
AESx(0xDE4A4A94), AESx(0xD44C4C98), AESx(0xE85858B0), AESx(0x4ACFCF85),
|
||||
AESx(0x6BD0D0BB), AESx(0x2AEFEFC5), AESx(0xE5AAAA4F), AESx(0x16FBFBED),
|
||||
AESx(0xC5434386), AESx(0xD74D4D9A), AESx(0x55333366), AESx(0x94858511),
|
||||
AESx(0xCF45458A), AESx(0x10F9F9E9), AESx(0x06020204), AESx(0x817F7FFE),
|
||||
AESx(0xF05050A0), AESx(0x443C3C78), AESx(0xBA9F9F25), AESx(0xE3A8A84B),
|
||||
AESx(0xF35151A2), AESx(0xFEA3A35D), AESx(0xC0404080), AESx(0x8A8F8F05),
|
||||
AESx(0xAD92923F), AESx(0xBC9D9D21), AESx(0x48383870), AESx(0x04F5F5F1),
|
||||
AESx(0xDFBCBC63), AESx(0xC1B6B677), AESx(0x75DADAAF), AESx(0x63212142),
|
||||
AESx(0x30101020), AESx(0x1AFFFFE5), AESx(0x0EF3F3FD), AESx(0x6DD2D2BF),
|
||||
AESx(0x4CCDCD81), AESx(0x140C0C18), AESx(0x35131326), AESx(0x2FECECC3),
|
||||
AESx(0xE15F5FBE), AESx(0xA2979735), AESx(0xCC444488), AESx(0x3917172E),
|
||||
AESx(0x57C4C493), AESx(0xF2A7A755), AESx(0x827E7EFC), AESx(0x473D3D7A),
|
||||
AESx(0xAC6464C8), AESx(0xE75D5DBA), AESx(0x2B191932), AESx(0x957373E6),
|
||||
AESx(0xA06060C0), AESx(0x98818119), AESx(0xD14F4F9E), AESx(0x7FDCDCA3),
|
||||
AESx(0x66222244), AESx(0x7E2A2A54), AESx(0xAB90903B), AESx(0x8388880B),
|
||||
AESx(0xCA46468C), AESx(0x29EEEEC7), AESx(0xD3B8B86B), AESx(0x3C141428),
|
||||
AESx(0x79DEDEA7), AESx(0xE25E5EBC), AESx(0x1D0B0B16), AESx(0x76DBDBAD),
|
||||
AESx(0x3BE0E0DB), AESx(0x56323264), AESx(0x4E3A3A74), AESx(0x1E0A0A14),
|
||||
AESx(0xDB494992), AESx(0x0A06060C), AESx(0x6C242448), AESx(0xE45C5CB8),
|
||||
AESx(0x5DC2C29F), AESx(0x6ED3D3BD), AESx(0xEFACAC43), AESx(0xA66262C4),
|
||||
AESx(0xA8919139), AESx(0xA4959531), AESx(0x37E4E4D3), AESx(0x8B7979F2),
|
||||
AESx(0x32E7E7D5), AESx(0x43C8C88B), AESx(0x5937376E), AESx(0xB76D6DDA),
|
||||
AESx(0x8C8D8D01), AESx(0x64D5D5B1), AESx(0xD24E4E9C), AESx(0xE0A9A949),
|
||||
AESx(0xB46C6CD8), AESx(0xFA5656AC), AESx(0x07F4F4F3), AESx(0x25EAEACF),
|
||||
AESx(0xAF6565CA), AESx(0x8E7A7AF4), AESx(0xE9AEAE47), AESx(0x18080810),
|
||||
AESx(0xD5BABA6F), AESx(0x887878F0), AESx(0x6F25254A), AESx(0x722E2E5C),
|
||||
AESx(0x241C1C38), AESx(0xF1A6A657), AESx(0xC7B4B473), AESx(0x51C6C697),
|
||||
AESx(0x23E8E8CB), AESx(0x7CDDDDA1), AESx(0x9C7474E8), AESx(0x211F1F3E),
|
||||
AESx(0xDD4B4B96), AESx(0xDCBDBD61), AESx(0x868B8B0D), AESx(0x858A8A0F),
|
||||
AESx(0x907070E0), AESx(0x423E3E7C), AESx(0xC4B5B571), AESx(0xAA6666CC),
|
||||
AESx(0xD8484890), AESx(0x05030306), AESx(0x01F6F6F7), AESx(0x120E0E1C),
|
||||
AESx(0xA36161C2), AESx(0x5F35356A), AESx(0xF95757AE), AESx(0xD0B9B969),
|
||||
AESx(0x91868617), AESx(0x58C1C199), AESx(0x271D1D3A), AESx(0xB99E9E27),
|
||||
AESx(0x38E1E1D9), AESx(0x13F8F8EB), AESx(0xB398982B), AESx(0x33111122),
|
||||
AESx(0xBB6969D2), AESx(0x70D9D9A9), AESx(0x898E8E07), AESx(0xA7949433),
|
||||
AESx(0xB69B9B2D), AESx(0x221E1E3C), AESx(0x92878715), AESx(0x20E9E9C9),
|
||||
AESx(0x49CECE87), AESx(0xFF5555AA), AESx(0x78282850), AESx(0x7ADFDFA5),
|
||||
AESx(0x8F8C8C03), AESx(0xF8A1A159), AESx(0x80898909), AESx(0x170D0D1A),
|
||||
AESx(0xDABFBF65), AESx(0x31E6E6D7), AESx(0xC6424284), AESx(0xB86868D0),
|
||||
AESx(0xC3414182), AESx(0xB0999929), AESx(0x772D2D5A), AESx(0x110F0F1E),
|
||||
AESx(0xCBB0B07B), AESx(0xFC5454A8), AESx(0xD6BBBB6D), AESx(0x3A16162C)
|
||||
};
|
||||
|
||||
static const sph_u32 AES1[256] = {
|
||||
AESx(0x6363C6A5), AESx(0x7C7CF884), AESx(0x7777EE99), AESx(0x7B7BF68D),
|
||||
AESx(0xF2F2FF0D), AESx(0x6B6BD6BD), AESx(0x6F6FDEB1), AESx(0xC5C59154),
|
||||
AESx(0x30306050), AESx(0x01010203), AESx(0x6767CEA9), AESx(0x2B2B567D),
|
||||
AESx(0xFEFEE719), AESx(0xD7D7B562), AESx(0xABAB4DE6), AESx(0x7676EC9A),
|
||||
AESx(0xCACA8F45), AESx(0x82821F9D), AESx(0xC9C98940), AESx(0x7D7DFA87),
|
||||
AESx(0xFAFAEF15), AESx(0x5959B2EB), AESx(0x47478EC9), AESx(0xF0F0FB0B),
|
||||
AESx(0xADAD41EC), AESx(0xD4D4B367), AESx(0xA2A25FFD), AESx(0xAFAF45EA),
|
||||
AESx(0x9C9C23BF), AESx(0xA4A453F7), AESx(0x7272E496), AESx(0xC0C09B5B),
|
||||
AESx(0xB7B775C2), AESx(0xFDFDE11C), AESx(0x93933DAE), AESx(0x26264C6A),
|
||||
AESx(0x36366C5A), AESx(0x3F3F7E41), AESx(0xF7F7F502), AESx(0xCCCC834F),
|
||||
AESx(0x3434685C), AESx(0xA5A551F4), AESx(0xE5E5D134), AESx(0xF1F1F908),
|
||||
AESx(0x7171E293), AESx(0xD8D8AB73), AESx(0x31316253), AESx(0x15152A3F),
|
||||
AESx(0x0404080C), AESx(0xC7C79552), AESx(0x23234665), AESx(0xC3C39D5E),
|
||||
AESx(0x18183028), AESx(0x969637A1), AESx(0x05050A0F), AESx(0x9A9A2FB5),
|
||||
AESx(0x07070E09), AESx(0x12122436), AESx(0x80801B9B), AESx(0xE2E2DF3D),
|
||||
AESx(0xEBEBCD26), AESx(0x27274E69), AESx(0xB2B27FCD), AESx(0x7575EA9F),
|
||||
AESx(0x0909121B), AESx(0x83831D9E), AESx(0x2C2C5874), AESx(0x1A1A342E),
|
||||
AESx(0x1B1B362D), AESx(0x6E6EDCB2), AESx(0x5A5AB4EE), AESx(0xA0A05BFB),
|
||||
AESx(0x5252A4F6), AESx(0x3B3B764D), AESx(0xD6D6B761), AESx(0xB3B37DCE),
|
||||
AESx(0x2929527B), AESx(0xE3E3DD3E), AESx(0x2F2F5E71), AESx(0x84841397),
|
||||
AESx(0x5353A6F5), AESx(0xD1D1B968), AESx(0x00000000), AESx(0xEDEDC12C),
|
||||
AESx(0x20204060), AESx(0xFCFCE31F), AESx(0xB1B179C8), AESx(0x5B5BB6ED),
|
||||
AESx(0x6A6AD4BE), AESx(0xCBCB8D46), AESx(0xBEBE67D9), AESx(0x3939724B),
|
||||
AESx(0x4A4A94DE), AESx(0x4C4C98D4), AESx(0x5858B0E8), AESx(0xCFCF854A),
|
||||
AESx(0xD0D0BB6B), AESx(0xEFEFC52A), AESx(0xAAAA4FE5), AESx(0xFBFBED16),
|
||||
AESx(0x434386C5), AESx(0x4D4D9AD7), AESx(0x33336655), AESx(0x85851194),
|
||||
AESx(0x45458ACF), AESx(0xF9F9E910), AESx(0x02020406), AESx(0x7F7FFE81),
|
||||
AESx(0x5050A0F0), AESx(0x3C3C7844), AESx(0x9F9F25BA), AESx(0xA8A84BE3),
|
||||
AESx(0x5151A2F3), AESx(0xA3A35DFE), AESx(0x404080C0), AESx(0x8F8F058A),
|
||||
AESx(0x92923FAD), AESx(0x9D9D21BC), AESx(0x38387048), AESx(0xF5F5F104),
|
||||
AESx(0xBCBC63DF), AESx(0xB6B677C1), AESx(0xDADAAF75), AESx(0x21214263),
|
||||
AESx(0x10102030), AESx(0xFFFFE51A), AESx(0xF3F3FD0E), AESx(0xD2D2BF6D),
|
||||
AESx(0xCDCD814C), AESx(0x0C0C1814), AESx(0x13132635), AESx(0xECECC32F),
|
||||
AESx(0x5F5FBEE1), AESx(0x979735A2), AESx(0x444488CC), AESx(0x17172E39),
|
||||
AESx(0xC4C49357), AESx(0xA7A755F2), AESx(0x7E7EFC82), AESx(0x3D3D7A47),
|
||||
AESx(0x6464C8AC), AESx(0x5D5DBAE7), AESx(0x1919322B), AESx(0x7373E695),
|
||||
AESx(0x6060C0A0), AESx(0x81811998), AESx(0x4F4F9ED1), AESx(0xDCDCA37F),
|
||||
AESx(0x22224466), AESx(0x2A2A547E), AESx(0x90903BAB), AESx(0x88880B83),
|
||||
AESx(0x46468CCA), AESx(0xEEEEC729), AESx(0xB8B86BD3), AESx(0x1414283C),
|
||||
AESx(0xDEDEA779), AESx(0x5E5EBCE2), AESx(0x0B0B161D), AESx(0xDBDBAD76),
|
||||
AESx(0xE0E0DB3B), AESx(0x32326456), AESx(0x3A3A744E), AESx(0x0A0A141E),
|
||||
AESx(0x494992DB), AESx(0x06060C0A), AESx(0x2424486C), AESx(0x5C5CB8E4),
|
||||
AESx(0xC2C29F5D), AESx(0xD3D3BD6E), AESx(0xACAC43EF), AESx(0x6262C4A6),
|
||||
AESx(0x919139A8), AESx(0x959531A4), AESx(0xE4E4D337), AESx(0x7979F28B),
|
||||
AESx(0xE7E7D532), AESx(0xC8C88B43), AESx(0x37376E59), AESx(0x6D6DDAB7),
|
||||
AESx(0x8D8D018C), AESx(0xD5D5B164), AESx(0x4E4E9CD2), AESx(0xA9A949E0),
|
||||
AESx(0x6C6CD8B4), AESx(0x5656ACFA), AESx(0xF4F4F307), AESx(0xEAEACF25),
|
||||
AESx(0x6565CAAF), AESx(0x7A7AF48E), AESx(0xAEAE47E9), AESx(0x08081018),
|
||||
AESx(0xBABA6FD5), AESx(0x7878F088), AESx(0x25254A6F), AESx(0x2E2E5C72),
|
||||
AESx(0x1C1C3824), AESx(0xA6A657F1), AESx(0xB4B473C7), AESx(0xC6C69751),
|
||||
AESx(0xE8E8CB23), AESx(0xDDDDA17C), AESx(0x7474E89C), AESx(0x1F1F3E21),
|
||||
AESx(0x4B4B96DD), AESx(0xBDBD61DC), AESx(0x8B8B0D86), AESx(0x8A8A0F85),
|
||||
AESx(0x7070E090), AESx(0x3E3E7C42), AESx(0xB5B571C4), AESx(0x6666CCAA),
|
||||
AESx(0x484890D8), AESx(0x03030605), AESx(0xF6F6F701), AESx(0x0E0E1C12),
|
||||
AESx(0x6161C2A3), AESx(0x35356A5F), AESx(0x5757AEF9), AESx(0xB9B969D0),
|
||||
AESx(0x86861791), AESx(0xC1C19958), AESx(0x1D1D3A27), AESx(0x9E9E27B9),
|
||||
AESx(0xE1E1D938), AESx(0xF8F8EB13), AESx(0x98982BB3), AESx(0x11112233),
|
||||
AESx(0x6969D2BB), AESx(0xD9D9A970), AESx(0x8E8E0789), AESx(0x949433A7),
|
||||
AESx(0x9B9B2DB6), AESx(0x1E1E3C22), AESx(0x87871592), AESx(0xE9E9C920),
|
||||
AESx(0xCECE8749), AESx(0x5555AAFF), AESx(0x28285078), AESx(0xDFDFA57A),
|
||||
AESx(0x8C8C038F), AESx(0xA1A159F8), AESx(0x89890980), AESx(0x0D0D1A17),
|
||||
AESx(0xBFBF65DA), AESx(0xE6E6D731), AESx(0x424284C6), AESx(0x6868D0B8),
|
||||
AESx(0x414182C3), AESx(0x999929B0), AESx(0x2D2D5A77), AESx(0x0F0F1E11),
|
||||
AESx(0xB0B07BCB), AESx(0x5454A8FC), AESx(0xBBBB6DD6), AESx(0x16162C3A)
|
||||
};
|
||||
|
||||
static const sph_u32 AES2[256] = {
|
||||
AESx(0x63C6A563), AESx(0x7CF8847C), AESx(0x77EE9977), AESx(0x7BF68D7B),
|
||||
AESx(0xF2FF0DF2), AESx(0x6BD6BD6B), AESx(0x6FDEB16F), AESx(0xC59154C5),
|
||||
AESx(0x30605030), AESx(0x01020301), AESx(0x67CEA967), AESx(0x2B567D2B),
|
||||
AESx(0xFEE719FE), AESx(0xD7B562D7), AESx(0xAB4DE6AB), AESx(0x76EC9A76),
|
||||
AESx(0xCA8F45CA), AESx(0x821F9D82), AESx(0xC98940C9), AESx(0x7DFA877D),
|
||||
AESx(0xFAEF15FA), AESx(0x59B2EB59), AESx(0x478EC947), AESx(0xF0FB0BF0),
|
||||
AESx(0xAD41ECAD), AESx(0xD4B367D4), AESx(0xA25FFDA2), AESx(0xAF45EAAF),
|
||||
AESx(0x9C23BF9C), AESx(0xA453F7A4), AESx(0x72E49672), AESx(0xC09B5BC0),
|
||||
AESx(0xB775C2B7), AESx(0xFDE11CFD), AESx(0x933DAE93), AESx(0x264C6A26),
|
||||
AESx(0x366C5A36), AESx(0x3F7E413F), AESx(0xF7F502F7), AESx(0xCC834FCC),
|
||||
AESx(0x34685C34), AESx(0xA551F4A5), AESx(0xE5D134E5), AESx(0xF1F908F1),
|
||||
AESx(0x71E29371), AESx(0xD8AB73D8), AESx(0x31625331), AESx(0x152A3F15),
|
||||
AESx(0x04080C04), AESx(0xC79552C7), AESx(0x23466523), AESx(0xC39D5EC3),
|
||||
AESx(0x18302818), AESx(0x9637A196), AESx(0x050A0F05), AESx(0x9A2FB59A),
|
||||
AESx(0x070E0907), AESx(0x12243612), AESx(0x801B9B80), AESx(0xE2DF3DE2),
|
||||
AESx(0xEBCD26EB), AESx(0x274E6927), AESx(0xB27FCDB2), AESx(0x75EA9F75),
|
||||
AESx(0x09121B09), AESx(0x831D9E83), AESx(0x2C58742C), AESx(0x1A342E1A),
|
||||
AESx(0x1B362D1B), AESx(0x6EDCB26E), AESx(0x5AB4EE5A), AESx(0xA05BFBA0),
|
||||
AESx(0x52A4F652), AESx(0x3B764D3B), AESx(0xD6B761D6), AESx(0xB37DCEB3),
|
||||
AESx(0x29527B29), AESx(0xE3DD3EE3), AESx(0x2F5E712F), AESx(0x84139784),
|
||||
AESx(0x53A6F553), AESx(0xD1B968D1), AESx(0x00000000), AESx(0xEDC12CED),
|
||||
AESx(0x20406020), AESx(0xFCE31FFC), AESx(0xB179C8B1), AESx(0x5BB6ED5B),
|
||||
AESx(0x6AD4BE6A), AESx(0xCB8D46CB), AESx(0xBE67D9BE), AESx(0x39724B39),
|
||||
AESx(0x4A94DE4A), AESx(0x4C98D44C), AESx(0x58B0E858), AESx(0xCF854ACF),
|
||||
AESx(0xD0BB6BD0), AESx(0xEFC52AEF), AESx(0xAA4FE5AA), AESx(0xFBED16FB),
|
||||
AESx(0x4386C543), AESx(0x4D9AD74D), AESx(0x33665533), AESx(0x85119485),
|
||||
AESx(0x458ACF45), AESx(0xF9E910F9), AESx(0x02040602), AESx(0x7FFE817F),
|
||||
AESx(0x50A0F050), AESx(0x3C78443C), AESx(0x9F25BA9F), AESx(0xA84BE3A8),
|
||||
AESx(0x51A2F351), AESx(0xA35DFEA3), AESx(0x4080C040), AESx(0x8F058A8F),
|
||||
AESx(0x923FAD92), AESx(0x9D21BC9D), AESx(0x38704838), AESx(0xF5F104F5),
|
||||
AESx(0xBC63DFBC), AESx(0xB677C1B6), AESx(0xDAAF75DA), AESx(0x21426321),
|
||||
AESx(0x10203010), AESx(0xFFE51AFF), AESx(0xF3FD0EF3), AESx(0xD2BF6DD2),
|
||||
AESx(0xCD814CCD), AESx(0x0C18140C), AESx(0x13263513), AESx(0xECC32FEC),
|
||||
AESx(0x5FBEE15F), AESx(0x9735A297), AESx(0x4488CC44), AESx(0x172E3917),
|
||||
AESx(0xC49357C4), AESx(0xA755F2A7), AESx(0x7EFC827E), AESx(0x3D7A473D),
|
||||
AESx(0x64C8AC64), AESx(0x5DBAE75D), AESx(0x19322B19), AESx(0x73E69573),
|
||||
AESx(0x60C0A060), AESx(0x81199881), AESx(0x4F9ED14F), AESx(0xDCA37FDC),
|
||||
AESx(0x22446622), AESx(0x2A547E2A), AESx(0x903BAB90), AESx(0x880B8388),
|
||||
AESx(0x468CCA46), AESx(0xEEC729EE), AESx(0xB86BD3B8), AESx(0x14283C14),
|
||||
AESx(0xDEA779DE), AESx(0x5EBCE25E), AESx(0x0B161D0B), AESx(0xDBAD76DB),
|
||||
AESx(0xE0DB3BE0), AESx(0x32645632), AESx(0x3A744E3A), AESx(0x0A141E0A),
|
||||
AESx(0x4992DB49), AESx(0x060C0A06), AESx(0x24486C24), AESx(0x5CB8E45C),
|
||||
AESx(0xC29F5DC2), AESx(0xD3BD6ED3), AESx(0xAC43EFAC), AESx(0x62C4A662),
|
||||
AESx(0x9139A891), AESx(0x9531A495), AESx(0xE4D337E4), AESx(0x79F28B79),
|
||||
AESx(0xE7D532E7), AESx(0xC88B43C8), AESx(0x376E5937), AESx(0x6DDAB76D),
|
||||
AESx(0x8D018C8D), AESx(0xD5B164D5), AESx(0x4E9CD24E), AESx(0xA949E0A9),
|
||||
AESx(0x6CD8B46C), AESx(0x56ACFA56), AESx(0xF4F307F4), AESx(0xEACF25EA),
|
||||
AESx(0x65CAAF65), AESx(0x7AF48E7A), AESx(0xAE47E9AE), AESx(0x08101808),
|
||||
AESx(0xBA6FD5BA), AESx(0x78F08878), AESx(0x254A6F25), AESx(0x2E5C722E),
|
||||
AESx(0x1C38241C), AESx(0xA657F1A6), AESx(0xB473C7B4), AESx(0xC69751C6),
|
||||
AESx(0xE8CB23E8), AESx(0xDDA17CDD), AESx(0x74E89C74), AESx(0x1F3E211F),
|
||||
AESx(0x4B96DD4B), AESx(0xBD61DCBD), AESx(0x8B0D868B), AESx(0x8A0F858A),
|
||||
AESx(0x70E09070), AESx(0x3E7C423E), AESx(0xB571C4B5), AESx(0x66CCAA66),
|
||||
AESx(0x4890D848), AESx(0x03060503), AESx(0xF6F701F6), AESx(0x0E1C120E),
|
||||
AESx(0x61C2A361), AESx(0x356A5F35), AESx(0x57AEF957), AESx(0xB969D0B9),
|
||||
AESx(0x86179186), AESx(0xC19958C1), AESx(0x1D3A271D), AESx(0x9E27B99E),
|
||||
AESx(0xE1D938E1), AESx(0xF8EB13F8), AESx(0x982BB398), AESx(0x11223311),
|
||||
AESx(0x69D2BB69), AESx(0xD9A970D9), AESx(0x8E07898E), AESx(0x9433A794),
|
||||
AESx(0x9B2DB69B), AESx(0x1E3C221E), AESx(0x87159287), AESx(0xE9C920E9),
|
||||
AESx(0xCE8749CE), AESx(0x55AAFF55), AESx(0x28507828), AESx(0xDFA57ADF),
|
||||
AESx(0x8C038F8C), AESx(0xA159F8A1), AESx(0x89098089), AESx(0x0D1A170D),
|
||||
AESx(0xBF65DABF), AESx(0xE6D731E6), AESx(0x4284C642), AESx(0x68D0B868),
|
||||
AESx(0x4182C341), AESx(0x9929B099), AESx(0x2D5A772D), AESx(0x0F1E110F),
|
||||
AESx(0xB07BCBB0), AESx(0x54A8FC54), AESx(0xBB6DD6BB), AESx(0x162C3A16)
|
||||
};
|
||||
|
||||
static const sph_u32 AES3[256] = {
|
||||
AESx(0xC6A56363), AESx(0xF8847C7C), AESx(0xEE997777), AESx(0xF68D7B7B),
|
||||
AESx(0xFF0DF2F2), AESx(0xD6BD6B6B), AESx(0xDEB16F6F), AESx(0x9154C5C5),
|
||||
AESx(0x60503030), AESx(0x02030101), AESx(0xCEA96767), AESx(0x567D2B2B),
|
||||
AESx(0xE719FEFE), AESx(0xB562D7D7), AESx(0x4DE6ABAB), AESx(0xEC9A7676),
|
||||
AESx(0x8F45CACA), AESx(0x1F9D8282), AESx(0x8940C9C9), AESx(0xFA877D7D),
|
||||
AESx(0xEF15FAFA), AESx(0xB2EB5959), AESx(0x8EC94747), AESx(0xFB0BF0F0),
|
||||
AESx(0x41ECADAD), AESx(0xB367D4D4), AESx(0x5FFDA2A2), AESx(0x45EAAFAF),
|
||||
AESx(0x23BF9C9C), AESx(0x53F7A4A4), AESx(0xE4967272), AESx(0x9B5BC0C0),
|
||||
AESx(0x75C2B7B7), AESx(0xE11CFDFD), AESx(0x3DAE9393), AESx(0x4C6A2626),
|
||||
AESx(0x6C5A3636), AESx(0x7E413F3F), AESx(0xF502F7F7), AESx(0x834FCCCC),
|
||||
AESx(0x685C3434), AESx(0x51F4A5A5), AESx(0xD134E5E5), AESx(0xF908F1F1),
|
||||
AESx(0xE2937171), AESx(0xAB73D8D8), AESx(0x62533131), AESx(0x2A3F1515),
|
||||
AESx(0x080C0404), AESx(0x9552C7C7), AESx(0x46652323), AESx(0x9D5EC3C3),
|
||||
AESx(0x30281818), AESx(0x37A19696), AESx(0x0A0F0505), AESx(0x2FB59A9A),
|
||||
AESx(0x0E090707), AESx(0x24361212), AESx(0x1B9B8080), AESx(0xDF3DE2E2),
|
||||
AESx(0xCD26EBEB), AESx(0x4E692727), AESx(0x7FCDB2B2), AESx(0xEA9F7575),
|
||||
AESx(0x121B0909), AESx(0x1D9E8383), AESx(0x58742C2C), AESx(0x342E1A1A),
|
||||
AESx(0x362D1B1B), AESx(0xDCB26E6E), AESx(0xB4EE5A5A), AESx(0x5BFBA0A0),
|
||||
AESx(0xA4F65252), AESx(0x764D3B3B), AESx(0xB761D6D6), AESx(0x7DCEB3B3),
|
||||
AESx(0x527B2929), AESx(0xDD3EE3E3), AESx(0x5E712F2F), AESx(0x13978484),
|
||||
AESx(0xA6F55353), AESx(0xB968D1D1), AESx(0x00000000), AESx(0xC12CEDED),
|
||||
AESx(0x40602020), AESx(0xE31FFCFC), AESx(0x79C8B1B1), AESx(0xB6ED5B5B),
|
||||
AESx(0xD4BE6A6A), AESx(0x8D46CBCB), AESx(0x67D9BEBE), AESx(0x724B3939),
|
||||
AESx(0x94DE4A4A), AESx(0x98D44C4C), AESx(0xB0E85858), AESx(0x854ACFCF),
|
||||
AESx(0xBB6BD0D0), AESx(0xC52AEFEF), AESx(0x4FE5AAAA), AESx(0xED16FBFB),
|
||||
AESx(0x86C54343), AESx(0x9AD74D4D), AESx(0x66553333), AESx(0x11948585),
|
||||
AESx(0x8ACF4545), AESx(0xE910F9F9), AESx(0x04060202), AESx(0xFE817F7F),
|
||||
AESx(0xA0F05050), AESx(0x78443C3C), AESx(0x25BA9F9F), AESx(0x4BE3A8A8),
|
||||
AESx(0xA2F35151), AESx(0x5DFEA3A3), AESx(0x80C04040), AESx(0x058A8F8F),
|
||||
AESx(0x3FAD9292), AESx(0x21BC9D9D), AESx(0x70483838), AESx(0xF104F5F5),
|
||||
AESx(0x63DFBCBC), AESx(0x77C1B6B6), AESx(0xAF75DADA), AESx(0x42632121),
|
||||
AESx(0x20301010), AESx(0xE51AFFFF), AESx(0xFD0EF3F3), AESx(0xBF6DD2D2),
|
||||
AESx(0x814CCDCD), AESx(0x18140C0C), AESx(0x26351313), AESx(0xC32FECEC),
|
||||
AESx(0xBEE15F5F), AESx(0x35A29797), AESx(0x88CC4444), AESx(0x2E391717),
|
||||
AESx(0x9357C4C4), AESx(0x55F2A7A7), AESx(0xFC827E7E), AESx(0x7A473D3D),
|
||||
AESx(0xC8AC6464), AESx(0xBAE75D5D), AESx(0x322B1919), AESx(0xE6957373),
|
||||
AESx(0xC0A06060), AESx(0x19988181), AESx(0x9ED14F4F), AESx(0xA37FDCDC),
|
||||
AESx(0x44662222), AESx(0x547E2A2A), AESx(0x3BAB9090), AESx(0x0B838888),
|
||||
AESx(0x8CCA4646), AESx(0xC729EEEE), AESx(0x6BD3B8B8), AESx(0x283C1414),
|
||||
AESx(0xA779DEDE), AESx(0xBCE25E5E), AESx(0x161D0B0B), AESx(0xAD76DBDB),
|
||||
AESx(0xDB3BE0E0), AESx(0x64563232), AESx(0x744E3A3A), AESx(0x141E0A0A),
|
||||
AESx(0x92DB4949), AESx(0x0C0A0606), AESx(0x486C2424), AESx(0xB8E45C5C),
|
||||
AESx(0x9F5DC2C2), AESx(0xBD6ED3D3), AESx(0x43EFACAC), AESx(0xC4A66262),
|
||||
AESx(0x39A89191), AESx(0x31A49595), AESx(0xD337E4E4), AESx(0xF28B7979),
|
||||
AESx(0xD532E7E7), AESx(0x8B43C8C8), AESx(0x6E593737), AESx(0xDAB76D6D),
|
||||
AESx(0x018C8D8D), AESx(0xB164D5D5), AESx(0x9CD24E4E), AESx(0x49E0A9A9),
|
||||
AESx(0xD8B46C6C), AESx(0xACFA5656), AESx(0xF307F4F4), AESx(0xCF25EAEA),
|
||||
AESx(0xCAAF6565), AESx(0xF48E7A7A), AESx(0x47E9AEAE), AESx(0x10180808),
|
||||
AESx(0x6FD5BABA), AESx(0xF0887878), AESx(0x4A6F2525), AESx(0x5C722E2E),
|
||||
AESx(0x38241C1C), AESx(0x57F1A6A6), AESx(0x73C7B4B4), AESx(0x9751C6C6),
|
||||
AESx(0xCB23E8E8), AESx(0xA17CDDDD), AESx(0xE89C7474), AESx(0x3E211F1F),
|
||||
AESx(0x96DD4B4B), AESx(0x61DCBDBD), AESx(0x0D868B8B), AESx(0x0F858A8A),
|
||||
AESx(0xE0907070), AESx(0x7C423E3E), AESx(0x71C4B5B5), AESx(0xCCAA6666),
|
||||
AESx(0x90D84848), AESx(0x06050303), AESx(0xF701F6F6), AESx(0x1C120E0E),
|
||||
AESx(0xC2A36161), AESx(0x6A5F3535), AESx(0xAEF95757), AESx(0x69D0B9B9),
|
||||
AESx(0x17918686), AESx(0x9958C1C1), AESx(0x3A271D1D), AESx(0x27B99E9E),
|
||||
AESx(0xD938E1E1), AESx(0xEB13F8F8), AESx(0x2BB39898), AESx(0x22331111),
|
||||
AESx(0xD2BB6969), AESx(0xA970D9D9), AESx(0x07898E8E), AESx(0x33A79494),
|
||||
AESx(0x2DB69B9B), AESx(0x3C221E1E), AESx(0x15928787), AESx(0xC920E9E9),
|
||||
AESx(0x8749CECE), AESx(0xAAFF5555), AESx(0x50782828), AESx(0xA57ADFDF),
|
||||
AESx(0x038F8C8C), AESx(0x59F8A1A1), AESx(0x09808989), AESx(0x1A170D0D),
|
||||
AESx(0x65DABFBF), AESx(0xD731E6E6), AESx(0x84C64242), AESx(0xD0B86868),
|
||||
AESx(0x82C34141), AESx(0x29B09999), AESx(0x5A772D2D), AESx(0x1E110F0F),
|
||||
AESx(0x7BCBB0B0), AESx(0xA8FC5454), AESx(0x6DD6BBBB), AESx(0x2C3A1616)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
142
packages/p2p/native/src/brg_endian.h
Normal file
142
packages/p2p/native/src/brg_endian.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
1. source code distributions include the above copyright notice, this
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
Changes for ARM 9/9/2010
|
||||
*/
|
||||
|
||||
#ifndef _BRG_ENDIAN_H
|
||||
#define _BRG_ENDIAN_H
|
||||
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
|
||||
#if 0
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||
# include <sys/endian.h>
|
||||
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
|
||||
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
|
||||
# include <machine/endian.h>
|
||||
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||
# include <endian.h>
|
||||
# if !defined( __BEOS__ )
|
||||
# include <byteswap.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Now attempt to set the define for platform byte order using any */
|
||||
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
|
||||
/* seem to encompass most endian symbol definitions */
|
||||
|
||||
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
|
||||
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
|
||||
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( _BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( _LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
|
||||
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
|
||||
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* if the platform byte order could not be determined, then try to */
|
||||
/* set this define using common machine defines */
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
|
||||
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||
defined( __VMS ) || defined( _M_X64 )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
|
||||
#elif defined(__arm__)
|
||||
# ifdef __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# else
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif 1 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
110
packages/p2p/native/src/common.h
Normal file
110
packages/p2p/native/src/common.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2026 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef DIGIBYTE_CRYPTO_COMMON_H
|
||||
#define DIGIBYTE_CRYPTO_COMMON_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/digibyte-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/endian.h>
|
||||
|
||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
memcpy(&x, ptr, 2);
|
||||
return le16toh(x);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||
{
|
||||
uint32_t x;
|
||||
memcpy(&x, ptr, 4);
|
||||
return le32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||
{
|
||||
uint64_t x;
|
||||
memcpy(&x, ptr, 8);
|
||||
return le64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||
{
|
||||
uint16_t v = htole16(x);
|
||||
memcpy(ptr, &v, 2);
|
||||
}
|
||||
|
||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
uint32_t v = htole32(x);
|
||||
memcpy(ptr, &v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
uint64_t v = htole64(x);
|
||||
memcpy(ptr, &v, 8);
|
||||
}
|
||||
|
||||
uint16_t static inline ReadBE16(const unsigned char* ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
memcpy(&x, ptr, 2);
|
||||
return be16toh(x);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||
{
|
||||
uint32_t x;
|
||||
memcpy(&x, ptr, 4);
|
||||
return be32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||
{
|
||||
uint64_t x;
|
||||
memcpy(&x, ptr, 8);
|
||||
return be64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
uint32_t v = htobe32(x);
|
||||
memcpy(ptr, &v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
uint64_t v = htobe64(x);
|
||||
memcpy(ptr, &v, 8);
|
||||
}
|
||||
|
||||
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */
|
||||
uint64_t static inline CountBits(uint64_t x)
|
||||
{
|
||||
#if HAVE_BUILTIN_CLZL
|
||||
if (sizeof(unsigned long) >= sizeof(uint64_t)) {
|
||||
return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0;
|
||||
}
|
||||
#endif
|
||||
#if HAVE_BUILTIN_CLZLL
|
||||
if (sizeof(unsigned long long) >= sizeof(uint64_t)) {
|
||||
return x ? 8 * sizeof(unsigned long long) - __builtin_clzll(x) : 0;
|
||||
}
|
||||
#endif
|
||||
int ret = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_COMMON_H
|
||||
723
packages/p2p/native/src/cubehash.cpp
Normal file
723
packages/p2p/native/src/cubehash.cpp
Normal file
|
|
@ -0,0 +1,723 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: cubehash.c 227 2010-06-16 17:28:38Z tp $ */
|
||||
/*
|
||||
* CubeHash implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "sph_cubehash.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
#define SPH_SMALL_FOOTPRINT_CUBEHASH 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some tests were conducted on an Intel Core2 Q6600 (32-bit and 64-bit
|
||||
* mode), a PowerPC G3, and a MIPS-compatible CPU (Broadcom BCM3302).
|
||||
* It appears that the optimal settings are:
|
||||
* -- full unroll, no state copy on the "big" systems (x86, PowerPC)
|
||||
* -- unroll to 4 or 8, state copy on the "small" system (MIPS)
|
||||
*/
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 4
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 0
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0xB0FC8217), SPH_C32(0x1BEE1A90), SPH_C32(0x829E1A22),
|
||||
SPH_C32(0x6362C342), SPH_C32(0x24D91C30), SPH_C32(0x03A7AA24),
|
||||
SPH_C32(0xA63721C8), SPH_C32(0x85B0E2EF), SPH_C32(0xF35D13F3),
|
||||
SPH_C32(0x41DA807D), SPH_C32(0x21A70CA6), SPH_C32(0x1F4E9774),
|
||||
SPH_C32(0xB3E1C932), SPH_C32(0xEB0A79A8), SPH_C32(0xCDDAAA66),
|
||||
SPH_C32(0xE2F6ECAA), SPH_C32(0x0A713362), SPH_C32(0xAA3080E0),
|
||||
SPH_C32(0xD8F23A32), SPH_C32(0xCEF15E28), SPH_C32(0xDB086314),
|
||||
SPH_C32(0x7F709DF7), SPH_C32(0xACD228A4), SPH_C32(0x704D6ECE),
|
||||
SPH_C32(0xAA3EC95F), SPH_C32(0xE387C214), SPH_C32(0x3A6445FF),
|
||||
SPH_C32(0x9CAB81C3), SPH_C32(0xC73D4B98), SPH_C32(0xD277AEBE),
|
||||
SPH_C32(0xFD20151C), SPH_C32(0x00CB573E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0xEA2BD4B4), SPH_C32(0xCCD6F29F), SPH_C32(0x63117E71),
|
||||
SPH_C32(0x35481EAE), SPH_C32(0x22512D5B), SPH_C32(0xE5D94E63),
|
||||
SPH_C32(0x7E624131), SPH_C32(0xF4CC12BE), SPH_C32(0xC2D0B696),
|
||||
SPH_C32(0x42AF2070), SPH_C32(0xD0720C35), SPH_C32(0x3361DA8C),
|
||||
SPH_C32(0x28CCECA4), SPH_C32(0x8EF8AD83), SPH_C32(0x4680AC00),
|
||||
SPH_C32(0x40E5FBAB), SPH_C32(0xD89041C3), SPH_C32(0x6107FBD5),
|
||||
SPH_C32(0x6C859D41), SPH_C32(0xF0B26679), SPH_C32(0x09392549),
|
||||
SPH_C32(0x5FA25603), SPH_C32(0x65C892FD), SPH_C32(0x93CB6285),
|
||||
SPH_C32(0x2AF2B5AE), SPH_C32(0x9E4B4E60), SPH_C32(0x774ABFDD),
|
||||
SPH_C32(0x85254725), SPH_C32(0x15815AEB), SPH_C32(0x4AB6AAD6),
|
||||
SPH_C32(0x9CDAF8AF), SPH_C32(0xD6032C0A)
|
||||
};
|
||||
|
||||
static const sph_u32 IV384[] = {
|
||||
SPH_C32(0xE623087E), SPH_C32(0x04C00C87), SPH_C32(0x5EF46453),
|
||||
SPH_C32(0x69524B13), SPH_C32(0x1A05C7A9), SPH_C32(0x3528DF88),
|
||||
SPH_C32(0x6BDD01B5), SPH_C32(0x5057B792), SPH_C32(0x6AA7A922),
|
||||
SPH_C32(0x649C7EEE), SPH_C32(0xF426309F), SPH_C32(0xCB629052),
|
||||
SPH_C32(0xFC8E20ED), SPH_C32(0xB3482BAB), SPH_C32(0xF89E5E7E),
|
||||
SPH_C32(0xD83D4DE4), SPH_C32(0x44BFC10D), SPH_C32(0x5FC1E63D),
|
||||
SPH_C32(0x2104E6CB), SPH_C32(0x17958F7F), SPH_C32(0xDBEAEF70),
|
||||
SPH_C32(0xB4B97E1E), SPH_C32(0x32C195F6), SPH_C32(0x6184A8E4),
|
||||
SPH_C32(0x796C2543), SPH_C32(0x23DE176D), SPH_C32(0xD33BBAEC),
|
||||
SPH_C32(0x0C12E5D2), SPH_C32(0x4EB95A7B), SPH_C32(0x2D18BA01),
|
||||
SPH_C32(0x04EE475F), SPH_C32(0x1FC5F22E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV512[] = {
|
||||
SPH_C32(0x2AEA2A61), SPH_C32(0x50F494D4), SPH_C32(0x2D538B8B),
|
||||
SPH_C32(0x4167D83E), SPH_C32(0x3FEE2313), SPH_C32(0xC701CF8C),
|
||||
SPH_C32(0xCC39968E), SPH_C32(0x50AC5695), SPH_C32(0x4D42C787),
|
||||
SPH_C32(0xA647A8B3), SPH_C32(0x97CF0BEF), SPH_C32(0x825B4537),
|
||||
SPH_C32(0xEEF864D2), SPH_C32(0xF22090C4), SPH_C32(0xD0E5CD33),
|
||||
SPH_C32(0xA23911AE), SPH_C32(0xFCD398D9), SPH_C32(0x148FE485),
|
||||
SPH_C32(0x1B017BEF), SPH_C32(0xB6444532), SPH_C32(0x6A536159),
|
||||
SPH_C32(0x2FF5781C), SPH_C32(0x91FA7934), SPH_C32(0x0DBADEA9),
|
||||
SPH_C32(0xD65C8A2B), SPH_C32(0xA5A70E75), SPH_C32(0xB1C62456),
|
||||
SPH_C32(0xBC796576), SPH_C32(0x1921C8F7), SPH_C32(0xE7989AF1),
|
||||
SPH_C32(0x7795D246), SPH_C32(0xD43E3B44)
|
||||
};
|
||||
|
||||
#define T32 SPH_T32
|
||||
#define ROTL32 SPH_ROTL32
|
||||
|
||||
#if SPH_CUBEHASH_NOCOPY
|
||||
|
||||
#define DECL_STATE
|
||||
#define READ_STATE(cc)
|
||||
#define WRITE_STATE(cc)
|
||||
|
||||
#define x0 ((sc)->state[ 0])
|
||||
#define x1 ((sc)->state[ 1])
|
||||
#define x2 ((sc)->state[ 2])
|
||||
#define x3 ((sc)->state[ 3])
|
||||
#define x4 ((sc)->state[ 4])
|
||||
#define x5 ((sc)->state[ 5])
|
||||
#define x6 ((sc)->state[ 6])
|
||||
#define x7 ((sc)->state[ 7])
|
||||
#define x8 ((sc)->state[ 8])
|
||||
#define x9 ((sc)->state[ 9])
|
||||
#define xa ((sc)->state[10])
|
||||
#define xb ((sc)->state[11])
|
||||
#define xc ((sc)->state[12])
|
||||
#define xd ((sc)->state[13])
|
||||
#define xe ((sc)->state[14])
|
||||
#define xf ((sc)->state[15])
|
||||
#define xg ((sc)->state[16])
|
||||
#define xh ((sc)->state[17])
|
||||
#define xi ((sc)->state[18])
|
||||
#define xj ((sc)->state[19])
|
||||
#define xk ((sc)->state[20])
|
||||
#define xl ((sc)->state[21])
|
||||
#define xm ((sc)->state[22])
|
||||
#define xn ((sc)->state[23])
|
||||
#define xo ((sc)->state[24])
|
||||
#define xp ((sc)->state[25])
|
||||
#define xq ((sc)->state[26])
|
||||
#define xr ((sc)->state[27])
|
||||
#define xs ((sc)->state[28])
|
||||
#define xt ((sc)->state[29])
|
||||
#define xu ((sc)->state[30])
|
||||
#define xv ((sc)->state[31])
|
||||
|
||||
#else
|
||||
|
||||
#define DECL_STATE \
|
||||
sph_u32 x0, x1, x2, x3, x4, x5, x6, x7; \
|
||||
sph_u32 x8, x9, xa, xb, xc, xd, xe, xf; \
|
||||
sph_u32 xg, xh, xi, xj, xk, xl, xm, xn; \
|
||||
sph_u32 xo, xp, xq, xr, xs, xt, xu, xv;
|
||||
|
||||
#define READ_STATE(cc) do { \
|
||||
x0 = (cc)->state[ 0]; \
|
||||
x1 = (cc)->state[ 1]; \
|
||||
x2 = (cc)->state[ 2]; \
|
||||
x3 = (cc)->state[ 3]; \
|
||||
x4 = (cc)->state[ 4]; \
|
||||
x5 = (cc)->state[ 5]; \
|
||||
x6 = (cc)->state[ 6]; \
|
||||
x7 = (cc)->state[ 7]; \
|
||||
x8 = (cc)->state[ 8]; \
|
||||
x9 = (cc)->state[ 9]; \
|
||||
xa = (cc)->state[10]; \
|
||||
xb = (cc)->state[11]; \
|
||||
xc = (cc)->state[12]; \
|
||||
xd = (cc)->state[13]; \
|
||||
xe = (cc)->state[14]; \
|
||||
xf = (cc)->state[15]; \
|
||||
xg = (cc)->state[16]; \
|
||||
xh = (cc)->state[17]; \
|
||||
xi = (cc)->state[18]; \
|
||||
xj = (cc)->state[19]; \
|
||||
xk = (cc)->state[20]; \
|
||||
xl = (cc)->state[21]; \
|
||||
xm = (cc)->state[22]; \
|
||||
xn = (cc)->state[23]; \
|
||||
xo = (cc)->state[24]; \
|
||||
xp = (cc)->state[25]; \
|
||||
xq = (cc)->state[26]; \
|
||||
xr = (cc)->state[27]; \
|
||||
xs = (cc)->state[28]; \
|
||||
xt = (cc)->state[29]; \
|
||||
xu = (cc)->state[30]; \
|
||||
xv = (cc)->state[31]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_STATE(cc) do { \
|
||||
(cc)->state[ 0] = x0; \
|
||||
(cc)->state[ 1] = x1; \
|
||||
(cc)->state[ 2] = x2; \
|
||||
(cc)->state[ 3] = x3; \
|
||||
(cc)->state[ 4] = x4; \
|
||||
(cc)->state[ 5] = x5; \
|
||||
(cc)->state[ 6] = x6; \
|
||||
(cc)->state[ 7] = x7; \
|
||||
(cc)->state[ 8] = x8; \
|
||||
(cc)->state[ 9] = x9; \
|
||||
(cc)->state[10] = xa; \
|
||||
(cc)->state[11] = xb; \
|
||||
(cc)->state[12] = xc; \
|
||||
(cc)->state[13] = xd; \
|
||||
(cc)->state[14] = xe; \
|
||||
(cc)->state[15] = xf; \
|
||||
(cc)->state[16] = xg; \
|
||||
(cc)->state[17] = xh; \
|
||||
(cc)->state[18] = xi; \
|
||||
(cc)->state[19] = xj; \
|
||||
(cc)->state[20] = xk; \
|
||||
(cc)->state[21] = xl; \
|
||||
(cc)->state[22] = xm; \
|
||||
(cc)->state[23] = xn; \
|
||||
(cc)->state[24] = xo; \
|
||||
(cc)->state[25] = xp; \
|
||||
(cc)->state[26] = xq; \
|
||||
(cc)->state[27] = xr; \
|
||||
(cc)->state[28] = xs; \
|
||||
(cc)->state[29] = xt; \
|
||||
(cc)->state[30] = xu; \
|
||||
(cc)->state[31] = xv; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define INPUT_BLOCK do { \
|
||||
x0 ^= sph_dec32le_aligned(buf + 0); \
|
||||
x1 ^= sph_dec32le_aligned(buf + 4); \
|
||||
x2 ^= sph_dec32le_aligned(buf + 8); \
|
||||
x3 ^= sph_dec32le_aligned(buf + 12); \
|
||||
x4 ^= sph_dec32le_aligned(buf + 16); \
|
||||
x5 ^= sph_dec32le_aligned(buf + 20); \
|
||||
x6 ^= sph_dec32le_aligned(buf + 24); \
|
||||
x7 ^= sph_dec32le_aligned(buf + 28); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_EVEN do { \
|
||||
xg = T32(x0 + xg); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xh = T32(x1 + xh); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xi = T32(x2 + xi); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xj = T32(x3 + xj); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
xk = T32(x4 + xk); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xl = T32(x5 + xl); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xm = T32(x6 + xm); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xn = T32(x7 + xn); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xo = T32(x8 + xo); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xp = T32(x9 + xp); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xq = T32(xa + xq); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xr = T32(xb + xr); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xs = T32(xc + xs); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xt = T32(xd + xt); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xu = T32(xe + xu); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xv = T32(xf + xv); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
x8 ^= xg; \
|
||||
x9 ^= xh; \
|
||||
xa ^= xi; \
|
||||
xb ^= xj; \
|
||||
xc ^= xk; \
|
||||
xd ^= xl; \
|
||||
xe ^= xm; \
|
||||
xf ^= xn; \
|
||||
x0 ^= xo; \
|
||||
x1 ^= xp; \
|
||||
x2 ^= xq; \
|
||||
x3 ^= xr; \
|
||||
x4 ^= xs; \
|
||||
x5 ^= xt; \
|
||||
x6 ^= xu; \
|
||||
x7 ^= xv; \
|
||||
xi = T32(x8 + xi); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xj = T32(x9 + xj); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xg = T32(xa + xg); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xh = T32(xb + xh); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
xm = T32(xc + xm); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xn = T32(xd + xn); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xk = T32(xe + xk); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xl = T32(xf + xl); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xq = T32(x0 + xq); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xr = T32(x1 + xr); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xo = T32(x2 + xo); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xp = T32(x3 + xp); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xu = T32(x4 + xu); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xv = T32(x5 + xv); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xs = T32(x6 + xs); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xt = T32(x7 + xt); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xc ^= xi; \
|
||||
xd ^= xj; \
|
||||
xe ^= xg; \
|
||||
xf ^= xh; \
|
||||
x8 ^= xm; \
|
||||
x9 ^= xn; \
|
||||
xa ^= xk; \
|
||||
xb ^= xl; \
|
||||
x4 ^= xq; \
|
||||
x5 ^= xr; \
|
||||
x6 ^= xo; \
|
||||
x7 ^= xp; \
|
||||
x0 ^= xu; \
|
||||
x1 ^= xv; \
|
||||
x2 ^= xs; \
|
||||
x3 ^= xt; \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_ODD do { \
|
||||
xj = T32(xc + xj); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xi = T32(xd + xi); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xh = T32(xe + xh); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xg = T32(xf + xg); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
xn = T32(x8 + xn); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xm = T32(x9 + xm); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xl = T32(xa + xl); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xk = T32(xb + xk); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xr = T32(x4 + xr); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xq = T32(x5 + xq); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xp = T32(x6 + xp); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xo = T32(x7 + xo); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xv = T32(x0 + xv); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xu = T32(x1 + xu); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xt = T32(x2 + xt); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xs = T32(x3 + xs); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
x4 ^= xj; \
|
||||
x5 ^= xi; \
|
||||
x6 ^= xh; \
|
||||
x7 ^= xg; \
|
||||
x0 ^= xn; \
|
||||
x1 ^= xm; \
|
||||
x2 ^= xl; \
|
||||
x3 ^= xk; \
|
||||
xc ^= xr; \
|
||||
xd ^= xq; \
|
||||
xe ^= xp; \
|
||||
xf ^= xo; \
|
||||
x8 ^= xv; \
|
||||
x9 ^= xu; \
|
||||
xa ^= xt; \
|
||||
xb ^= xs; \
|
||||
xh = T32(x4 + xh); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xg = T32(x5 + xg); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xj = T32(x6 + xj); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xi = T32(x7 + xi); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xl = T32(x0 + xl); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xk = T32(x1 + xk); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xn = T32(x2 + xn); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xm = T32(x3 + xm); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xp = T32(xc + xp); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xo = T32(xd + xo); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xr = T32(xe + xr); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xq = T32(xf + xq); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xt = T32(x8 + xt); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xs = T32(x9 + xs); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xv = T32(xa + xv); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xu = T32(xb + xu); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
x0 ^= xh; \
|
||||
x1 ^= xg; \
|
||||
x2 ^= xj; \
|
||||
x3 ^= xi; \
|
||||
x4 ^= xl; \
|
||||
x5 ^= xk; \
|
||||
x6 ^= xn; \
|
||||
x7 ^= xm; \
|
||||
x8 ^= xp; \
|
||||
x9 ^= xo; \
|
||||
xa ^= xr; \
|
||||
xb ^= xq; \
|
||||
xc ^= xt; \
|
||||
xd ^= xs; \
|
||||
xe ^= xv; \
|
||||
xf ^= xu; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* There is no need to unroll all 16 rounds. The word-swapping permutation
|
||||
* is an involution, so we need to unroll an even number of rounds. On
|
||||
* "big" systems, unrolling 4 rounds yields about 97% of the speed
|
||||
* achieved with full unrolling; and it keeps the code more compact
|
||||
* for small architectures.
|
||||
*/
|
||||
|
||||
#if SPH_CUBEHASH_UNROLL == 2
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 8; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 4
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 4; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 8
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 2; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
memcpy(sc->state, iv, sizeof sc->state);
|
||||
sc->ptr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
if (len < (sizeof sc->buf) - ptr) {
|
||||
memcpy(buf + ptr, data, len);
|
||||
ptr += len;
|
||||
sc->ptr = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
READ_STATE(sc);
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
ptr += clen;
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
INPUT_BLOCK;
|
||||
SIXTEEN_ROUNDS;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
sc->ptr = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr;
|
||||
unsigned z;
|
||||
int i;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
READ_STATE(sc);
|
||||
INPUT_BLOCK;
|
||||
for (i = 0; i < 11; i ++) {
|
||||
SIXTEEN_ROUNDS;
|
||||
if (i == 0)
|
||||
xv ^= SPH_C32(1);
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
out = (unsigned char*) dst;
|
||||
for (z = 0; z < out_size_w32; z ++)
|
||||
sph_enc32le(out + (z << 2), sc->state[z]);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash224_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 7);
|
||||
sph_cubehash224_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash256_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 8);
|
||||
sph_cubehash256_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash384_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 12);
|
||||
sph_cubehash384_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash512_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 16);
|
||||
sph_cubehash512_init(cc);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
8
packages/p2p/native/src/displayIntermediateValues.h
Normal file
8
packages/p2p/native/src/displayIntermediateValues.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Stub for the Keccak reference implementation's optional debug tracing.
|
||||
// Core ships without this header too; the macros expand to nothing.
|
||||
#ifndef DISPLAY_INTERMEDIATE_VALUES_STUB
|
||||
#define DISPLAY_INTERMEDIATE_VALUES_STUB
|
||||
#define displayRoundNumber(...)
|
||||
#define displayStateAsBytes(...)
|
||||
#define displayStateAsLanes(...)
|
||||
#endif
|
||||
1032
packages/p2p/native/src/echo.cpp
Normal file
1032
packages/p2p/native/src/echo.cpp
Normal file
File diff suppressed because it is too large
Load diff
3119
packages/p2p/native/src/groestl.cpp
Normal file
3119
packages/p2p/native/src/groestl.cpp
Normal file
File diff suppressed because it is too large
Load diff
1428
packages/p2p/native/src/luffa.cpp
Normal file
1428
packages/p2p/native/src/luffa.cpp
Normal file
File diff suppressed because it is too large
Load diff
301
packages/p2p/native/src/odocrypt.cpp
Normal file
301
packages/p2p/native/src/odocrypt.cpp
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The DigiByte developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "odocrypt.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
struct OdoRandom
|
||||
{
|
||||
// LCG parameters from Knuth
|
||||
const static uint64_t BASE_MULTIPLICAND = 6364136223846793005ull;
|
||||
const static uint64_t BASE_ADDEND = 1442695040888963407ull;
|
||||
|
||||
OdoRandom(uint32_t seed):
|
||||
current(seed),
|
||||
multiplicand(1),
|
||||
addend(0)
|
||||
{}
|
||||
|
||||
// For a standard LCG, every seed produces the same sequence, but from a different
|
||||
// starting point. This generator gives the 1st, 3rd, 6th, 10th, etc output from
|
||||
// a standard LCG. This ensures that every seed produces a unique sequence.
|
||||
inline uint32_t NextInt()
|
||||
{
|
||||
addend += multiplicand * BASE_ADDEND;
|
||||
multiplicand *= BASE_MULTIPLICAND;
|
||||
current = current * multiplicand + addend;
|
||||
return current >> 32;
|
||||
}
|
||||
|
||||
inline uint64_t NextLong()
|
||||
{
|
||||
uint64_t hi = NextInt();
|
||||
return (hi << 32) | NextInt();
|
||||
}
|
||||
|
||||
inline int Next(int N)
|
||||
{
|
||||
return ((uint64_t)NextInt() * N) >> 32;
|
||||
}
|
||||
|
||||
template<class T, size_t sz>
|
||||
void Permutation(T (&arr)[sz])
|
||||
{
|
||||
for (size_t i = 0; i < sz; i++)
|
||||
arr[i] = i;
|
||||
for (size_t i = 1; i < sz; i++)
|
||||
std::swap(arr[i], arr[Next(i+1)]);
|
||||
}
|
||||
|
||||
uint64_t current;
|
||||
uint64_t multiplicand;
|
||||
uint64_t addend;
|
||||
};
|
||||
|
||||
OdoCrypt::OdoCrypt(uint32_t key)
|
||||
{
|
||||
OdoRandom r(key);
|
||||
|
||||
// Randomize each s-box
|
||||
for (int i = 0; i < SMALL_SBOX_COUNT; i++)
|
||||
{
|
||||
r.Permutation(Sbox1[i]);
|
||||
}
|
||||
for (int i = 0; i < LARGE_SBOX_COUNT; i++)
|
||||
{
|
||||
r.Permutation(Sbox2[i]);
|
||||
}
|
||||
|
||||
// Randomize each p-box
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Pbox& perm = Permutation[i];
|
||||
for (int j = 0; j < PBOX_SUBROUNDS; j++)
|
||||
for (int k = 0; k < STATE_SIZE/2; k++)
|
||||
perm.mask[j][k] = r.NextLong();
|
||||
for (int j = 0; j < PBOX_SUBROUNDS-1; j++)
|
||||
for (int k = 0; k < STATE_SIZE/2; k++)
|
||||
perm.rotation[j][k] = r.Next(63) + 1;
|
||||
}
|
||||
|
||||
// Randomize rotations
|
||||
// Rotations must be distinct, non-zero, and have odd sum
|
||||
{
|
||||
int bits[WORD_BITS-1];
|
||||
r.Permutation(bits);
|
||||
int sum = 0;
|
||||
for (int j = 0; j < ROTATION_COUNT-1; j++)
|
||||
{
|
||||
Rotations[j] = bits[j] + 1;
|
||||
sum += Rotations[j];
|
||||
}
|
||||
for (int j = ROTATION_COUNT-1; ; j++)
|
||||
{
|
||||
if ((bits[j] + 1 + sum) % 2)
|
||||
{
|
||||
Rotations[ROTATION_COUNT-1] = bits[j] + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Randomize each round key
|
||||
for (int i = 0; i < ROUNDS; i++)
|
||||
RoundKey[i] = r.Next(1 << STATE_SIZE);
|
||||
}
|
||||
|
||||
void OdoCrypt::Encrypt(char cipher[DIGEST_SIZE], const char plain[DIGEST_SIZE]) const
|
||||
{
|
||||
uint64_t state[STATE_SIZE];
|
||||
Unpack(state, plain);
|
||||
PreMix(state);
|
||||
for (int round = 0; round < ROUNDS; round++)
|
||||
{
|
||||
ApplyPbox(state, Permutation[0]);
|
||||
ApplySboxes(state, Sbox1, Sbox2);
|
||||
ApplyPbox(state, Permutation[1]);
|
||||
ApplyRotations(state, Rotations);
|
||||
ApplyRoundKey(state, RoundKey[round]);
|
||||
}
|
||||
Pack(state, cipher);
|
||||
}
|
||||
|
||||
template<class T, size_t sz1, size_t sz2>
|
||||
void InvertMapping(T (&res)[sz1][sz2], const T (&mapping)[sz1][sz2])
|
||||
{
|
||||
for (size_t i = 0; i < sz1; i++)
|
||||
for (size_t j = 0; j < sz2; j++)
|
||||
res[i][mapping[i][j]] = j;
|
||||
}
|
||||
|
||||
void OdoCrypt::Decrypt(char plain[DIGEST_SIZE], const char cipher[DIGEST_SIZE]) const
|
||||
{
|
||||
uint8_t invSbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH];
|
||||
uint16_t invSbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH];
|
||||
|
||||
InvertMapping(invSbox1, Sbox1);
|
||||
InvertMapping(invSbox2, Sbox2);
|
||||
|
||||
uint64_t state[STATE_SIZE];
|
||||
Unpack(state, cipher);
|
||||
for (int round = ROUNDS-1; round >= 0; round--)
|
||||
{
|
||||
ApplyRoundKey(state, RoundKey[round]);
|
||||
// LCM(STATE_SIZE, WORD_BITS)-1 is enough iterations, but this will do.
|
||||
for (int i = 0; i < STATE_SIZE*WORD_BITS-1; i++)
|
||||
ApplyRotations(state, Rotations);
|
||||
ApplyInvPbox(state, Permutation[1]);
|
||||
ApplySboxes(state, invSbox1, invSbox2);
|
||||
ApplyInvPbox(state, Permutation[0]);
|
||||
}
|
||||
PreMix(state);
|
||||
Pack(state, plain);
|
||||
}
|
||||
|
||||
void OdoCrypt::Unpack(uint64_t state[STATE_SIZE], const char bytes[DIGEST_SIZE])
|
||||
{
|
||||
std::fill(state, state+STATE_SIZE, 0);
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
state[i] |= (uint64_t)(uint8_t)bytes[8*i + j] << (8*j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::Pack(const uint64_t state[STATE_SIZE], char bytes[DIGEST_SIZE])
|
||||
{
|
||||
std::fill(bytes, bytes+DIGEST_SIZE, 0);
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
bytes[8*i + j] = (state[i] >> (8*j)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::PreMix(uint64_t state[STATE_SIZE])
|
||||
{
|
||||
uint64_t total = 0;
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
total ^= state[i];
|
||||
total ^= total >> 32;
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
state[i] ^= total;
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplySboxes(
|
||||
uint64_t state[STATE_SIZE],
|
||||
const uint8_t sbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH],
|
||||
const uint16_t sbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH])
|
||||
{
|
||||
const static uint64_t MASK1 = (1 << SMALL_SBOX_WIDTH) - 1;
|
||||
const static uint64_t MASK2 = (1 << LARGE_SBOX_WIDTH) - 1;
|
||||
|
||||
int smallSboxIndex = 0;
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
{
|
||||
uint64_t next = 0;
|
||||
int pos = 0;
|
||||
int largeSboxIndex = i;
|
||||
for (int j = 0; j < SMALL_SBOX_COUNT / STATE_SIZE; j++)
|
||||
{
|
||||
next |= (uint64_t)sbox1[smallSboxIndex][(state[i] >> pos) & MASK1] << pos;
|
||||
pos += SMALL_SBOX_WIDTH;
|
||||
next |= (uint64_t)sbox2[largeSboxIndex][(state[i] >> pos) & MASK2] << pos;
|
||||
pos += LARGE_SBOX_WIDTH;
|
||||
smallSboxIndex++;
|
||||
}
|
||||
state[i] = next;
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyMaskedSwaps(uint64_t state[STATE_SIZE], const uint64_t mask[STATE_SIZE/2])
|
||||
{
|
||||
for (int i = 0; i < STATE_SIZE/2; i++)
|
||||
{
|
||||
uint64_t& a = state[2*i];
|
||||
uint64_t& b = state[2*i+1];
|
||||
// For each bit set in the mask, swap the corresponding bits in `a` and `b`
|
||||
uint64_t swp = mask[i] & (a ^ b);
|
||||
a ^= swp;
|
||||
b ^= swp;
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyWordShuffle(uint64_t state[STATE_SIZE], int m)
|
||||
{
|
||||
uint64_t next[STATE_SIZE];
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
{
|
||||
next[m*i % STATE_SIZE] = state[i];
|
||||
}
|
||||
std::copy(next, next+STATE_SIZE, state);
|
||||
}
|
||||
|
||||
inline uint64_t Rot(uint64_t x, int r)
|
||||
{
|
||||
return r == 0 ? x : (x << r) ^ (x >> (64-r));
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyPboxRotations(uint64_t state[STATE_SIZE], const int rotation[STATE_SIZE/2])
|
||||
{
|
||||
for (int i = 0; i < STATE_SIZE/2; i++)
|
||||
{
|
||||
// Only rotate the even words. Rotating the odd words wouldn't actually
|
||||
// be useful - a transformation that rotates all the words can be
|
||||
// transformed into one that only rotates the even words, then rotates
|
||||
// the odd words once after the final iteration.
|
||||
state[2*i] = Rot(state[2*i], rotation[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyPbox(uint64_t state[STATE_SIZE], const Pbox& perm)
|
||||
{
|
||||
for (int i = 0; i < PBOX_SUBROUNDS-1; i++)
|
||||
{
|
||||
// Conditionally move bits between adjacent pairs of words
|
||||
ApplyMaskedSwaps(state, perm.mask[i]);
|
||||
// Move the words around
|
||||
ApplyWordShuffle(state, PBOX_M);
|
||||
// Rotate the bits within words
|
||||
ApplyPboxRotations(state, perm.rotation[i]);
|
||||
}
|
||||
ApplyMaskedSwaps(state, perm.mask[PBOX_SUBROUNDS-1]);
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyInvPbox(uint64_t state[STATE_SIZE], const Pbox& perm)
|
||||
{
|
||||
ApplyMaskedSwaps(state, perm.mask[PBOX_SUBROUNDS-1]);
|
||||
for (int i = PBOX_SUBROUNDS-2; i >= 0; i--)
|
||||
{
|
||||
int invRotation[STATE_SIZE/2];
|
||||
for (int j = 0; j < STATE_SIZE/2; j++)
|
||||
invRotation[j] = WORD_BITS - perm.rotation[i][j];
|
||||
ApplyPboxRotations(state, invRotation);
|
||||
ApplyWordShuffle(state, INV_PBOX_M);
|
||||
ApplyMaskedSwaps(state, perm.mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyRotations(uint64_t state[STATE_SIZE], const int rotations[ROTATION_COUNT])
|
||||
{
|
||||
uint64_t next[STATE_SIZE];
|
||||
std::rotate_copy(state, state+1, state+STATE_SIZE, next);
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
for (int j = 0; j < ROTATION_COUNT; j++)
|
||||
{
|
||||
next[i] ^= Rot(state[i], rotations[j]);
|
||||
}
|
||||
std::copy(next, next+STATE_SIZE, state);
|
||||
}
|
||||
|
||||
void OdoCrypt::ApplyRoundKey(uint64_t state[STATE_SIZE], int roundKey)
|
||||
{
|
||||
for (int i = 0; i < STATE_SIZE; i++)
|
||||
state[i] ^= (roundKey >> i) & 1;
|
||||
}
|
||||
96
packages/p2p/native/src/odocrypt.h
Normal file
96
packages/p2p/native/src/odocrypt.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The DigiByte developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef ODO_CRYPT
|
||||
#define ODO_CRYPT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class OdoCrypt
|
||||
{
|
||||
public:
|
||||
// Block size, in bytes
|
||||
const static int DIGEST_SIZE = 80;
|
||||
|
||||
private:
|
||||
// Number of rounds.
|
||||
const static int ROUNDS = 84;
|
||||
// Odo utilizes two sbox sizes - 6-bit sboxes, which are ideally suited for
|
||||
// FPGA logic elements, and 10-bit sboxes, which are ideally suited for FPGA
|
||||
// RAM elements.
|
||||
const static int SMALL_SBOX_WIDTH = 6;
|
||||
const static int LARGE_SBOX_WIDTH = 10;
|
||||
// The pboxes are constructed using 3 primitives, applied multiple times.
|
||||
const static int PBOX_SUBROUNDS = 6;
|
||||
// This constant should be a generator for the multiplicative group of
|
||||
// integers modulo STATE_SIZE (3 or 7 for a STATE_SIZE of 10). It controls
|
||||
// one part of the pbox step.
|
||||
const static int PBOX_M = 3;
|
||||
// The multiplicative inverse of PBOX_M modulo STATE_SIZE
|
||||
const static int INV_PBOX_M = 7;
|
||||
// This constant must be even. It controls the number of rotations used in
|
||||
// the linear mixing step.
|
||||
const static int ROTATION_COUNT = 6;
|
||||
// Odo internally operates on 64-bit words.
|
||||
const static int WORD_BITS = 64;
|
||||
|
||||
const static int DIGEST_BITS = 8*DIGEST_SIZE;
|
||||
const static int STATE_SIZE = DIGEST_BITS / WORD_BITS;
|
||||
const static int SMALL_SBOX_COUNT = DIGEST_BITS / (SMALL_SBOX_WIDTH + LARGE_SBOX_WIDTH);
|
||||
const static int LARGE_SBOX_COUNT = STATE_SIZE;
|
||||
|
||||
public:
|
||||
OdoCrypt(uint32_t key);
|
||||
|
||||
void Encrypt(char cipher[DIGEST_SIZE], const char plain[DIGEST_SIZE]) const;
|
||||
|
||||
// test-only, proves that this really is a permutation function
|
||||
void Decrypt(char plain[DIGEST_SIZE], const char cipher[DIGEST_SIZE]) const;
|
||||
|
||||
private:
|
||||
struct Pbox
|
||||
{
|
||||
uint64_t mask[PBOX_SUBROUNDS][STATE_SIZE/2];
|
||||
int rotation[PBOX_SUBROUNDS-1][STATE_SIZE/2];
|
||||
};
|
||||
|
||||
uint8_t Sbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH];
|
||||
uint16_t Sbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH];
|
||||
Pbox Permutation[2];
|
||||
int Rotations[ROTATION_COUNT];
|
||||
uint16_t RoundKey[ROUNDS];
|
||||
|
||||
// Pack/unpack bytes into internal state
|
||||
static void Unpack(uint64_t state[STATE_SIZE], const char bytes[DIGEST_SIZE]);
|
||||
static void Pack(const uint64_t state[STATE_SIZE], char bytes[DIGEST_SIZE]);
|
||||
|
||||
// Pre-mix the bits. Involution. After this step, 95% of the bits depend
|
||||
// on a bit from the nonce.
|
||||
static void PreMix(uint64_t state[STATE_SIZE]);
|
||||
|
||||
// Non-linear substitution.
|
||||
static void ApplySboxes(
|
||||
uint64_t state[STATE_SIZE],
|
||||
const uint8_t sbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH],
|
||||
const uint16_t sbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH]);
|
||||
|
||||
// ApplyPbox helpers
|
||||
static void ApplyMaskedSwaps(uint64_t state[STATE_SIZE], const uint64_t mask[STATE_SIZE/2]);
|
||||
static void ApplyWordShuffle(uint64_t state[STATE_SIZE], int m);
|
||||
static void ApplyPboxRotations(uint64_t state[STATE_SIZE], const int rotation[STATE_SIZE/2]);
|
||||
|
||||
// Permute the bits.
|
||||
static void ApplyPbox(uint64_t state[STATE_SIZE], const Pbox& perm);
|
||||
|
||||
// Inverse transform of ApplyPbox. Only used by Decrypt.
|
||||
static void ApplyInvPbox(uint64_t state[STATE_SIZE], const Pbox& perm);
|
||||
|
||||
// Linear mix step.
|
||||
static void ApplyRotations(uint64_t state[STATE_SIZE], const int rotations[ROTATION_COUNT]);
|
||||
|
||||
// Add round key. Involution.
|
||||
static void ApplyRoundKey(uint64_t state[STATE_SIZE], int roundKey);
|
||||
};
|
||||
|
||||
#endif
|
||||
256
packages/p2p/native/src/scrypt.cpp
Normal file
256
packages/p2p/native/src/scrypt.cpp
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/* Copyright 2009 Colin Percival, 2011 ArtForz, 2012-2013 pooler
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
*/
|
||||
/*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* This file was originally written by Colin Percival as part of the Tarsnap
|
||||
* online backup system.
|
||||
*/
|
||||
|
||||
#include "crypto/scrypt.h"
|
||||
#include "crypto/hmac_sha256.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(USE_SSE2) && !defined(USE_SSE2_ALWAYS)
|
||||
#ifdef _MSC_VER
|
||||
// MSVC 64bit is unable to use inline asm
|
||||
#include <intrin.h>
|
||||
#else
|
||||
// GCC Linux or i686-w64-mingw32
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Scrypt-specific endian function to avoid conflicts with system headers
|
||||
// This works with potentially unaligned pointers and is portable across all platforms
|
||||
static inline void scrypt_be32enc(void *pp, uint32_t x)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
p[3] = x & 0xff;
|
||||
p[2] = (x >> 8) & 0xff;
|
||||
p[1] = (x >> 16) & 0xff;
|
||||
p[0] = (x >> 24) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void
|
||||
PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
|
||||
size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen)
|
||||
{
|
||||
CHMAC_SHA256 hctx(NULL, 0);
|
||||
size_t i;
|
||||
uint8_t ivec[4];
|
||||
uint8_t U[32];
|
||||
uint8_t T[32];
|
||||
uint64_t j;
|
||||
int k;
|
||||
size_t clen;
|
||||
|
||||
/* Compute HMAC state after processing P and S. */
|
||||
CHMAC_SHA256 PShctx(passwd, passwdlen);
|
||||
PShctx.Write(salt, saltlen);
|
||||
|
||||
/* Iterate through the blocks. */
|
||||
for (i = 0; i * 32 < dkLen; i++) {
|
||||
/* Generate INT(i + 1). */
|
||||
scrypt_be32enc(ivec, (uint32_t)(i + 1));
|
||||
|
||||
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||
memcpy(&hctx, &PShctx, sizeof(CHMAC_SHA256));
|
||||
hctx.Write(ivec, 4);
|
||||
hctx.Finalize(U);
|
||||
|
||||
/* T_i = U_1 ... */
|
||||
memcpy(T, U, 32);
|
||||
|
||||
for (j = 2; j <= c; j++) {
|
||||
/* Compute U_j. */
|
||||
hctx = CHMAC_SHA256(passwd, passwdlen);
|
||||
hctx.Write(U, 32);
|
||||
hctx.Finalize(U);
|
||||
|
||||
/* ... xor U_j ... */
|
||||
for (k = 0; k < 32; k++)
|
||||
T[k] ^= U[k];
|
||||
}
|
||||
|
||||
/* Copy as many bytes as necessary into buf. */
|
||||
clen = dkLen - i * 32;
|
||||
if (clen > 32)
|
||||
clen = 32;
|
||||
memcpy(&buf[i * 32], T, clen);
|
||||
}
|
||||
|
||||
/* Clean PShctx, since we never called _Final on it. */
|
||||
PShctx.Reset();
|
||||
}
|
||||
|
||||
#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||
|
||||
static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16])
|
||||
{
|
||||
uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15;
|
||||
int i;
|
||||
|
||||
x00 = (B[ 0] ^= Bx[ 0]);
|
||||
x01 = (B[ 1] ^= Bx[ 1]);
|
||||
x02 = (B[ 2] ^= Bx[ 2]);
|
||||
x03 = (B[ 3] ^= Bx[ 3]);
|
||||
x04 = (B[ 4] ^= Bx[ 4]);
|
||||
x05 = (B[ 5] ^= Bx[ 5]);
|
||||
x06 = (B[ 6] ^= Bx[ 6]);
|
||||
x07 = (B[ 7] ^= Bx[ 7]);
|
||||
x08 = (B[ 8] ^= Bx[ 8]);
|
||||
x09 = (B[ 9] ^= Bx[ 9]);
|
||||
x10 = (B[10] ^= Bx[10]);
|
||||
x11 = (B[11] ^= Bx[11]);
|
||||
x12 = (B[12] ^= Bx[12]);
|
||||
x13 = (B[13] ^= Bx[13]);
|
||||
x14 = (B[14] ^= Bx[14]);
|
||||
x15 = (B[15] ^= Bx[15]);
|
||||
for (i = 0; i < 8; i += 2) {
|
||||
/* Operate on columns. */
|
||||
x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7);
|
||||
x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7);
|
||||
|
||||
x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9);
|
||||
x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9);
|
||||
|
||||
x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13);
|
||||
x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13);
|
||||
|
||||
x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18);
|
||||
x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18);
|
||||
|
||||
/* Operate on rows. */
|
||||
x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7);
|
||||
x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7);
|
||||
|
||||
x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9);
|
||||
x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9);
|
||||
|
||||
x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13);
|
||||
x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13);
|
||||
|
||||
x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18);
|
||||
x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18);
|
||||
}
|
||||
B[ 0] += x00;
|
||||
B[ 1] += x01;
|
||||
B[ 2] += x02;
|
||||
B[ 3] += x03;
|
||||
B[ 4] += x04;
|
||||
B[ 5] += x05;
|
||||
B[ 6] += x06;
|
||||
B[ 7] += x07;
|
||||
B[ 8] += x08;
|
||||
B[ 9] += x09;
|
||||
B[10] += x10;
|
||||
B[11] += x11;
|
||||
B[12] += x12;
|
||||
B[13] += x13;
|
||||
B[14] += x14;
|
||||
B[15] += x15;
|
||||
}
|
||||
|
||||
void scrypt_1024_1_1_256_sp_generic(const char *input, char *output, char *scratchpad)
|
||||
{
|
||||
uint8_t B[128];
|
||||
uint32_t X[32];
|
||||
uint32_t *V;
|
||||
uint32_t i, j, k;
|
||||
|
||||
V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
|
||||
|
||||
PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128);
|
||||
|
||||
for (k = 0; k < 32; k++)
|
||||
X[k] = scrypt_le32dec(&B[4 * k]);
|
||||
|
||||
for (i = 0; i < 1024; i++) {
|
||||
memcpy(&V[i * 32], X, 128);
|
||||
xor_salsa8(&X[0], &X[16]);
|
||||
xor_salsa8(&X[16], &X[0]);
|
||||
}
|
||||
for (i = 0; i < 1024; i++) {
|
||||
j = 32 * (X[16] & 1023);
|
||||
for (k = 0; k < 32; k++)
|
||||
X[k] ^= V[j + k];
|
||||
xor_salsa8(&X[0], &X[16]);
|
||||
xor_salsa8(&X[16], &X[0]);
|
||||
}
|
||||
|
||||
for (k = 0; k < 32; k++)
|
||||
scrypt_le32enc(&B[4 * k], X[k]);
|
||||
|
||||
PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32);
|
||||
}
|
||||
|
||||
#if defined(USE_SSE2)
|
||||
// By default, set to generic scrypt function. This will prevent crash in case when scrypt_detect_sse2() wasn't called
|
||||
void (*scrypt_1024_1_1_256_sp_detected)(const char *input, char *output, char *scratchpad) = &scrypt_1024_1_1_256_sp_generic;
|
||||
|
||||
void scrypt_detect_sse2()
|
||||
{
|
||||
#if defined(USE_SSE2_ALWAYS)
|
||||
printf("scrypt: using scrypt-sse2 as built.\n");
|
||||
#else // USE_SSE2_ALWAYS
|
||||
// 32bit x86 Linux or Windows, detect cpuid features
|
||||
unsigned int cpuid_edx=0;
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC
|
||||
int x86cpuid[4];
|
||||
__cpuid(x86cpuid, 1);
|
||||
cpuid_edx = (unsigned int)buffer[3];
|
||||
#else // _MSC_VER
|
||||
// Linux or i686-w64-mingw32 (gcc-4.6.3)
|
||||
unsigned int eax, ebx, ecx;
|
||||
__get_cpuid(1, &eax, &ebx, &ecx, &cpuid_edx);
|
||||
#endif // _MSC_VER
|
||||
|
||||
if (cpuid_edx & 1<<26)
|
||||
{
|
||||
scrypt_1024_1_1_256_sp_detected = &scrypt_1024_1_1_256_sp_sse2;
|
||||
printf("scrypt: using scrypt-sse2 as detected.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
scrypt_1024_1_1_256_sp_detected = &scrypt_1024_1_1_256_sp_generic;
|
||||
printf("scrypt: using scrypt-generic, SSE2 unavailable.\n");
|
||||
}
|
||||
#endif // USE_SSE2_ALWAYS
|
||||
}
|
||||
#endif
|
||||
|
||||
void scrypt_1024_1_1_256(const char *input, char *output)
|
||||
{
|
||||
char scratchpad[SCRYPT_SCRATCHPAD_SIZE];
|
||||
scrypt_1024_1_1_256_sp(input, output, scratchpad);
|
||||
}
|
||||
47
packages/p2p/native/src/scrypt.h
Normal file
47
packages/p2p/native/src/scrypt.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef SCRYPT_H
|
||||
#define SCRYPT_H
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static const int SCRYPT_SCRATCHPAD_SIZE = 131072 + 63;
|
||||
|
||||
void scrypt_1024_1_1_256(const char *input, char *output);
|
||||
void scrypt_1024_1_1_256_sp_generic(const char *input, char *output, char *scratchpad);
|
||||
|
||||
#if defined(USE_SSE2)
|
||||
#if defined(_M_X64) || defined(__x86_64__) || defined(_M_AMD64) || (defined(MAC_OSX) && defined(__i386__))
|
||||
#define USE_SSE2_ALWAYS 1
|
||||
#define scrypt_1024_1_1_256_sp(input, output, scratchpad) scrypt_1024_1_1_256_sp_sse2((input), (output), (scratchpad))
|
||||
#else
|
||||
#define scrypt_1024_1_1_256_sp(input, output, scratchpad) scrypt_1024_1_1_256_sp_detected((input), (output), (scratchpad))
|
||||
#endif
|
||||
|
||||
void scrypt_detect_sse2();
|
||||
void scrypt_1024_1_1_256_sp_sse2(const char *input, char *output, char *scratchpad);
|
||||
extern void (*scrypt_1024_1_1_256_sp_detected)(const char *input, char *output, char *scratchpad);
|
||||
#else
|
||||
#define scrypt_1024_1_1_256_sp(input, output, scratchpad) scrypt_1024_1_1_256_sp_generic((input), (output), (scratchpad))
|
||||
#endif
|
||||
|
||||
void
|
||||
PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
|
||||
size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen);
|
||||
|
||||
// Scrypt-specific endian functions to avoid conflicts with system headers
|
||||
// These work with potentially unaligned pointers and are portable across all platforms
|
||||
static inline uint32_t scrypt_le32dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
|
||||
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
|
||||
}
|
||||
|
||||
static inline void scrypt_le32enc(void *pp, uint32_t x)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
p[0] = x & 0xff;
|
||||
p[1] = (x >> 8) & 0xff;
|
||||
p[2] = (x >> 16) & 0xff;
|
||||
p[3] = (x >> 24) & 0xff;
|
||||
}
|
||||
#endif
|
||||
775
packages/p2p/native/src/sha256.cpp
Normal file
775
packages/p2p/native/src/sha256.cpp
Normal file
|
|
@ -0,0 +1,775 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2026 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include <crypto/sha256.h>
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/cpuid.h>
|
||||
|
||||
#if defined(__linux__) && defined(ENABLE_ARM_SHANI) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
#endif
|
||||
|
||||
#if defined(MAC_OSX) && defined(ENABLE_ARM_SHANI) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||
#if defined(USE_ASM)
|
||||
namespace sha256_sse4
|
||||
{
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace sha256d64_sse41
|
||||
{
|
||||
void Transform_4way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256d64_avx2
|
||||
{
|
||||
void Transform_8way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256d64_x86_shani
|
||||
{
|
||||
void Transform_2way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256_x86_shani
|
||||
{
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
|
||||
}
|
||||
|
||||
namespace sha256_arm_shani
|
||||
{
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
|
||||
}
|
||||
|
||||
namespace sha256d64_arm_shani
|
||||
{
|
||||
void Transform_2way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// Internal SHA-256 implementation.
|
||||
namespace sha256
|
||||
{
|
||||
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
|
||||
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
|
||||
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
|
||||
uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
|
||||
uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
|
||||
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
|
||||
|
||||
/** One round of SHA-256. */
|
||||
void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k)
|
||||
{
|
||||
uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k;
|
||||
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||
d += t1;
|
||||
h = t1 + t2;
|
||||
}
|
||||
|
||||
/** Initialize SHA-256 state. */
|
||||
void inline Initialize(uint32_t* s)
|
||||
{
|
||||
s[0] = 0x6a09e667ul;
|
||||
s[1] = 0xbb67ae85ul;
|
||||
s[2] = 0x3c6ef372ul;
|
||||
s[3] = 0xa54ff53aul;
|
||||
s[4] = 0x510e527ful;
|
||||
s[5] = 0x9b05688cul;
|
||||
s[6] = 0x1f83d9abul;
|
||||
s[7] = 0x5be0cd19ul;
|
||||
}
|
||||
|
||||
/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
|
||||
{
|
||||
while (blocks--) {
|
||||
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98 + (w0 = ReadBE32(chunk + 0)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491 + (w1 = ReadBE32(chunk + 4)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf + (w2 = ReadBE32(chunk + 8)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5 + (w3 = ReadBE32(chunk + 12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25b + (w4 = ReadBE32(chunk + 16)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1 + (w5 = ReadBE32(chunk + 20)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4 + (w6 = ReadBE32(chunk + 24)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5 + (w7 = ReadBE32(chunk + 28)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98 + (w8 = ReadBE32(chunk + 32)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01 + (w9 = ReadBE32(chunk + 36)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185be + (w10 = ReadBE32(chunk + 40)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3 + (w11 = ReadBE32(chunk + 44)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74 + (w12 = ReadBE32(chunk + 48)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1fe + (w13 = ReadBE32(chunk + 52)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7 + (w14 = ReadBE32(chunk + 56)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf174 + (w15 = ReadBE32(chunk + 60)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6 + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1cc + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6f + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aa + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988da + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66d + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abb + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92e + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664b + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774c + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82ee + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636f + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffa + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506ceb + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7 + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2 + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
s[5] += f;
|
||||
s[6] += g;
|
||||
s[7] += h;
|
||||
chunk += 64;
|
||||
}
|
||||
}
|
||||
|
||||
void TransformD64(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
// Transform 1
|
||||
uint32_t a = 0x6a09e667ul;
|
||||
uint32_t b = 0xbb67ae85ul;
|
||||
uint32_t c = 0x3c6ef372ul;
|
||||
uint32_t d = 0xa54ff53aul;
|
||||
uint32_t e = 0x510e527ful;
|
||||
uint32_t f = 0x9b05688cul;
|
||||
uint32_t g = 0x1f83d9abul;
|
||||
uint32_t h = 0x5be0cd19ul;
|
||||
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
a += 0x6a09e667ul;
|
||||
b += 0xbb67ae85ul;
|
||||
c += 0x3c6ef372ul;
|
||||
d += 0xa54ff53aul;
|
||||
e += 0x510e527ful;
|
||||
f += 0x9b05688cul;
|
||||
g += 0x1f83d9abul;
|
||||
h += 0x5be0cd19ul;
|
||||
|
||||
uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
|
||||
|
||||
// Transform 2
|
||||
Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful);
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf374ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x649b69c1ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x240cf254ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x4fe9346ful);
|
||||
Round(d, e, f, g, h, a, b, c, 0x6cc984beul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x61b9411eul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x16f988faul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xf2c65152ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb019fc65ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xfdb1232bul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x3069bad5ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xcb976d5ful);
|
||||
Round(g, h, a, b, c, d, e, f, 0x5a0f118ful);
|
||||
Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x0a35b689ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x007f3e86ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x37088980ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xa507ea32ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x6fab9537ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x17406110ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x83613bdaul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xdb48a363ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x0b02e931ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x521afacaul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x31338431ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x6d437890ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x9eccabbdul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x532fb63cul);
|
||||
Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x07237ea3ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xa4954b68ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x4c191d76ul);
|
||||
|
||||
w0 = t0 + a;
|
||||
w1 = t1 + b;
|
||||
w2 = t2 + c;
|
||||
w3 = t3 + d;
|
||||
w4 = t4 + e;
|
||||
w5 = t5 + f;
|
||||
w6 = t6 + g;
|
||||
w7 = t7 + h;
|
||||
|
||||
// Transform 3
|
||||
a = 0x6a09e667ul;
|
||||
b = 0xbb67ae85ul;
|
||||
c = 0x3c6ef372ul;
|
||||
d = 0xa54ff53aul;
|
||||
e = 0x510e527ful;
|
||||
f = 0x9b05688cul;
|
||||
g = 0x1f83d9abul;
|
||||
h = 0x5be0cd19ul;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0);
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2);
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3);
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4);
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5);
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6);
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7);
|
||||
Round(a, b, c, d, e, f, g, h, 0x5807aa98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf274ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
// Output
|
||||
WriteBE32(out + 0, a + 0x6a09e667ul);
|
||||
WriteBE32(out + 4, b + 0xbb67ae85ul);
|
||||
WriteBE32(out + 8, c + 0x3c6ef372ul);
|
||||
WriteBE32(out + 12, d + 0xa54ff53aul);
|
||||
WriteBE32(out + 16, e + 0x510e527ful);
|
||||
WriteBE32(out + 20, f + 0x9b05688cul);
|
||||
WriteBE32(out + 24, g + 0x1f83d9abul);
|
||||
WriteBE32(out + 28, h + 0x5be0cd19ul);
|
||||
}
|
||||
|
||||
} // namespace sha256
|
||||
|
||||
typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
|
||||
typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
|
||||
|
||||
template<TransformType tr>
|
||||
void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
uint32_t s[8];
|
||||
static const unsigned char padding1[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
|
||||
};
|
||||
unsigned char buffer2[64] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
|
||||
};
|
||||
sha256::Initialize(s);
|
||||
tr(s, in, 1);
|
||||
tr(s, padding1, 1);
|
||||
WriteBE32(buffer2 + 0, s[0]);
|
||||
WriteBE32(buffer2 + 4, s[1]);
|
||||
WriteBE32(buffer2 + 8, s[2]);
|
||||
WriteBE32(buffer2 + 12, s[3]);
|
||||
WriteBE32(buffer2 + 16, s[4]);
|
||||
WriteBE32(buffer2 + 20, s[5]);
|
||||
WriteBE32(buffer2 + 24, s[6]);
|
||||
WriteBE32(buffer2 + 28, s[7]);
|
||||
sha256::Initialize(s);
|
||||
tr(s, buffer2, 1);
|
||||
WriteBE32(out + 0, s[0]);
|
||||
WriteBE32(out + 4, s[1]);
|
||||
WriteBE32(out + 8, s[2]);
|
||||
WriteBE32(out + 12, s[3]);
|
||||
WriteBE32(out + 16, s[4]);
|
||||
WriteBE32(out + 20, s[5]);
|
||||
WriteBE32(out + 24, s[6]);
|
||||
WriteBE32(out + 28, s[7]);
|
||||
}
|
||||
|
||||
TransformType Transform = sha256::Transform;
|
||||
TransformD64Type TransformD64 = sha256::TransformD64;
|
||||
TransformD64Type TransformD64_2way = nullptr;
|
||||
TransformD64Type TransformD64_4way = nullptr;
|
||||
TransformD64Type TransformD64_8way = nullptr;
|
||||
|
||||
bool SelfTest() {
|
||||
// Input state (equal to the initial SHA256 state)
|
||||
static const uint32_t init[8] = {
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
};
|
||||
// Some random input data to test with
|
||||
static const unsigned char data[641] = "-" // Intentionally not aligned
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m"
|
||||
"olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor"
|
||||
"bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N"
|
||||
"unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer"
|
||||
"mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce"
|
||||
" id velit. Telus in metus vulputate eu scelerisque felis. Mi tem"
|
||||
"pus imperdiet nulla malesuada pellentesque. Tristique magna sit.";
|
||||
// Expected output state for hashing the i*64 first input bytes above (excluding SHA256 padding).
|
||||
static const uint32_t result[9][8] = {
|
||||
{0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul},
|
||||
{0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul},
|
||||
{0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul},
|
||||
{0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul},
|
||||
{0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul},
|
||||
{0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul},
|
||||
{0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul},
|
||||
{0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul},
|
||||
{0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul},
|
||||
};
|
||||
// Expected output for each of the individual 8 64-byte messages under full double SHA256 (including padding).
|
||||
static const unsigned char result_d64[256] = {
|
||||
0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0,
|
||||
0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52,
|
||||
0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25,
|
||||
0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7,
|
||||
0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45,
|
||||
0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e,
|
||||
0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16,
|
||||
0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9,
|
||||
0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8,
|
||||
0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1,
|
||||
0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7,
|
||||
0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d,
|
||||
0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84,
|
||||
0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e,
|
||||
0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a,
|
||||
0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51
|
||||
};
|
||||
|
||||
|
||||
// Test Transform() for 0 through 8 transformations.
|
||||
for (size_t i = 0; i <= 8; ++i) {
|
||||
uint32_t state[8];
|
||||
std::copy(init, init + 8, state);
|
||||
Transform(state, data + 1, i);
|
||||
if (!std::equal(state, state + 8, result[i])) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64
|
||||
unsigned char out[32];
|
||||
TransformD64(out, data + 1);
|
||||
if (!std::equal(out, out + 32, result_d64)) return false;
|
||||
|
||||
// Test TransformD64_2way, if available.
|
||||
if (TransformD64_2way) {
|
||||
unsigned char out[64];
|
||||
TransformD64_2way(out, data + 1);
|
||||
if (!std::equal(out, out + 64, result_d64)) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64_4way, if available.
|
||||
if (TransformD64_4way) {
|
||||
unsigned char out[128];
|
||||
TransformD64_4way(out, data + 1);
|
||||
if (!std::equal(out, out + 128, result_d64)) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64_8way, if available.
|
||||
if (TransformD64_8way) {
|
||||
unsigned char out[256];
|
||||
TransformD64_8way(out, data + 1);
|
||||
if (!std::equal(out, out + 256, result_d64)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
|
||||
/** Check whether the OS has enabled AVX registers. */
|
||||
bool AVXEnabled()
|
||||
{
|
||||
uint32_t a, d;
|
||||
__asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
|
||||
return (a & 6) == 6;
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
|
||||
std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implementation)
|
||||
{
|
||||
std::string ret = "standard";
|
||||
Transform = sha256::Transform;
|
||||
TransformD64 = sha256::TransformD64;
|
||||
TransformD64_2way = nullptr;
|
||||
TransformD64_4way = nullptr;
|
||||
TransformD64_8way = nullptr;
|
||||
#if defined(USE_ASM) && defined(HAVE_GETCPUID)
|
||||
bool have_sse4 = false;
|
||||
bool have_xsave = false;
|
||||
bool have_avx = false;
|
||||
[[maybe_unused]] bool have_avx2 = false;
|
||||
[[maybe_unused]] bool have_x86_shani = false;
|
||||
[[maybe_unused]] bool enabled_avx = false;
|
||||
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
GetCPUID(1, 0, eax, ebx, ecx, edx);
|
||||
if (use_implementation & sha256_implementation::USE_SSE4) {
|
||||
have_sse4 = (ecx >> 19) & 1;
|
||||
}
|
||||
have_xsave = (ecx >> 27) & 1;
|
||||
have_avx = (ecx >> 28) & 1;
|
||||
if (have_xsave && have_avx) {
|
||||
enabled_avx = AVXEnabled();
|
||||
}
|
||||
if (have_sse4) {
|
||||
GetCPUID(7, 0, eax, ebx, ecx, edx);
|
||||
if (use_implementation & sha256_implementation::USE_AVX2) {
|
||||
have_avx2 = (ebx >> 5) & 1;
|
||||
}
|
||||
if (use_implementation & sha256_implementation::USE_SHANI) {
|
||||
have_x86_shani = (ebx >> 29) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ENABLE_X86_SHANI) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
if (have_x86_shani) {
|
||||
Transform = sha256_x86_shani::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_x86_shani::Transform>;
|
||||
TransformD64_2way = sha256d64_x86_shani::Transform_2way;
|
||||
ret = "x86_shani(1way,2way)";
|
||||
have_sse4 = false; // Disable SSE4/AVX2;
|
||||
have_avx2 = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (have_sse4) {
|
||||
#if defined(__x86_64__) || defined(__amd64__)
|
||||
Transform = sha256_sse4::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
|
||||
ret = "sse4(1way)";
|
||||
#endif
|
||||
#if defined(ENABLE_SSE41) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
TransformD64_4way = sha256d64_sse41::Transform_4way;
|
||||
ret += ",sse41(4way)";
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ENABLE_AVX2) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
if (have_avx2 && have_avx && enabled_avx) {
|
||||
TransformD64_8way = sha256d64_avx2::Transform_8way;
|
||||
ret += ",avx2(8way)";
|
||||
}
|
||||
#endif
|
||||
#endif // defined(USE_ASM) && defined(HAVE_GETCPUID)
|
||||
|
||||
#if defined(ENABLE_ARM_SHANI) && !defined(BUILD_DIGIBYTE_INTERNAL)
|
||||
bool have_arm_shani = false;
|
||||
if (use_implementation & sha256_implementation::USE_SHANI) {
|
||||
#if defined(__linux__)
|
||||
#if defined(__arm__) // 32-bit
|
||||
if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) {
|
||||
have_arm_shani = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(__aarch64__) // 64-bit
|
||||
if (getauxval(AT_HWCAP) & HWCAP_SHA2) {
|
||||
have_arm_shani = true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MAC_OSX)
|
||||
int val = 0;
|
||||
size_t len = sizeof(val);
|
||||
if (sysctlbyname("hw.optional.arm.FEAT_SHA256", &val, &len, nullptr, 0) == 0) {
|
||||
have_arm_shani = val != 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (have_arm_shani) {
|
||||
Transform = sha256_arm_shani::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_arm_shani::Transform>;
|
||||
TransformD64_2way = sha256d64_arm_shani::Transform_2way;
|
||||
ret = "arm_shani(1way,2way)";
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(SelfTest());
|
||||
return ret;
|
||||
}
|
||||
|
||||
////// SHA-256
|
||||
|
||||
CSHA256::CSHA256()
|
||||
{
|
||||
sha256::Initialize(s);
|
||||
}
|
||||
|
||||
CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
const unsigned char* end = data + len;
|
||||
size_t bufsize = bytes % 64;
|
||||
if (bufsize && bufsize + len >= 64) {
|
||||
// Fill the buffer, and process it.
|
||||
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||
bytes += 64 - bufsize;
|
||||
data += 64 - bufsize;
|
||||
Transform(s, buf, 1);
|
||||
bufsize = 0;
|
||||
}
|
||||
if (end - data >= 64) {
|
||||
size_t blocks = (end - data) / 64;
|
||||
Transform(s, data, blocks);
|
||||
data += 64 * blocks;
|
||||
bytes += 64 * blocks;
|
||||
}
|
||||
if (end > data) {
|
||||
// Fill the buffer with what remains.
|
||||
memcpy(buf + bufsize, data, end - data);
|
||||
bytes += end - data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
static const unsigned char pad[64] = {0x80};
|
||||
unsigned char sizedesc[8];
|
||||
WriteBE64(sizedesc, bytes << 3);
|
||||
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||
Write(sizedesc, 8);
|
||||
WriteBE32(hash, s[0]);
|
||||
WriteBE32(hash + 4, s[1]);
|
||||
WriteBE32(hash + 8, s[2]);
|
||||
WriteBE32(hash + 12, s[3]);
|
||||
WriteBE32(hash + 16, s[4]);
|
||||
WriteBE32(hash + 20, s[5]);
|
||||
WriteBE32(hash + 24, s[6]);
|
||||
WriteBE32(hash + 28, s[7]);
|
||||
}
|
||||
|
||||
CSHA256& CSHA256::Reset()
|
||||
{
|
||||
bytes = 0;
|
||||
sha256::Initialize(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
|
||||
{
|
||||
if (TransformD64_8way) {
|
||||
while (blocks >= 8) {
|
||||
TransformD64_8way(out, in);
|
||||
out += 256;
|
||||
in += 512;
|
||||
blocks -= 8;
|
||||
}
|
||||
}
|
||||
if (TransformD64_4way) {
|
||||
while (blocks >= 4) {
|
||||
TransformD64_4way(out, in);
|
||||
out += 128;
|
||||
in += 256;
|
||||
blocks -= 4;
|
||||
}
|
||||
}
|
||||
if (TransformD64_2way) {
|
||||
while (blocks >= 2) {
|
||||
TransformD64_2way(out, in);
|
||||
out += 64;
|
||||
in += 128;
|
||||
blocks -= 2;
|
||||
}
|
||||
}
|
||||
while (blocks) {
|
||||
TransformD64(out, in);
|
||||
out += 32;
|
||||
in += 64;
|
||||
--blocks;
|
||||
}
|
||||
}
|
||||
53
packages/p2p/native/src/sha256.h
Normal file
53
packages/p2p/native/src/sha256.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2026 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef DIGIBYTE_CRYPTO_SHA256_H
|
||||
#define DIGIBYTE_CRYPTO_SHA256_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
/** A hasher class for SHA-256. */
|
||||
class CSHA256
|
||||
{
|
||||
private:
|
||||
uint32_t s[8];
|
||||
unsigned char buf[64];
|
||||
uint64_t bytes{0};
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 32;
|
||||
|
||||
CSHA256();
|
||||
CSHA256& Write(const unsigned char* data, size_t len);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CSHA256& Reset();
|
||||
};
|
||||
|
||||
namespace sha256_implementation {
|
||||
enum UseImplementation : uint8_t {
|
||||
STANDARD = 0,
|
||||
USE_SSE4 = 1 << 0,
|
||||
USE_AVX2 = 1 << 1,
|
||||
USE_SHANI = 1 << 2,
|
||||
USE_SSE4_AND_AVX2 = USE_SSE4 | USE_AVX2,
|
||||
USE_SSE4_AND_SHANI = USE_SSE4 | USE_SHANI,
|
||||
USE_ALL = USE_SSE4 | USE_AVX2 | USE_SHANI,
|
||||
};
|
||||
}
|
||||
|
||||
/** Autodetect the best available SHA256 implementation.
|
||||
* Returns the name of the implementation.
|
||||
*/
|
||||
std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implementation = sha256_implementation::USE_ALL);
|
||||
|
||||
/** Compute multiple double-SHA256's of 64-byte blobs.
|
||||
* output: pointer to a blocks*32 byte output buffer
|
||||
* input: pointer to a blocks*64 byte input buffer
|
||||
* blocks: the number of hashes to compute.
|
||||
*/
|
||||
void SHA256D64(unsigned char* output, const unsigned char* input, size_t blocks);
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SHA256_H
|
||||
1764
packages/p2p/native/src/shavite.cpp
Normal file
1764
packages/p2p/native/src/shavite.cpp
Normal file
File diff suppressed because it is too large
Load diff
1799
packages/p2p/native/src/simd.cpp
Normal file
1799
packages/p2p/native/src/simd.cpp
Normal file
File diff suppressed because it is too large
Load diff
1254
packages/p2p/native/src/skein.cpp
Normal file
1254
packages/p2p/native/src/skein.cpp
Normal file
File diff suppressed because it is too large
Load diff
292
packages/p2p/native/src/sph_cubehash.h
Normal file
292
packages/p2p/native/src/sph_cubehash.h
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_cubehash.h 180 2010-05-08 02:29:25Z tp $ */
|
||||
/**
|
||||
* CubeHash interface. CubeHash is a family of functions which differ by
|
||||
* their output size; this implementation defines CubeHash for output
|
||||
* sizes 224, 256, 384 and 512 bits, with the "standard parameters"
|
||||
* (CubeHash16/32 with the CubeHash specification notations).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_cubehash.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_CUBEHASH_H__
|
||||
#define SPH_CUBEHASH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-224.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-256.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-384.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-512.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for CubeHash computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* a CubeHash computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running CubeHash computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[32];
|
||||
#endif
|
||||
} sph_cubehash_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash224_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash256_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash384_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash512_context;
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-224 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-224 context (pointer to a
|
||||
* <code>sph_cubehash224_context</code>)
|
||||
*/
|
||||
void sph_cubehash224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-256 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-256 context (pointer to a
|
||||
* <code>sph_cubehash256_context</code>)
|
||||
*/
|
||||
void sph_cubehash256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-384 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-384 context (pointer to a
|
||||
* <code>sph_cubehash384_context</code>)
|
||||
*/
|
||||
void sph_cubehash384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-512 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-512 context (pointer to a
|
||||
* <code>sph_cubehash512_context</code>)
|
||||
*/
|
||||
void sph_cubehash512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
320
packages/p2p/native/src/sph_echo.h
Normal file
320
packages/p2p/native/src/sph_echo.h
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_echo.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* ECHO interface. ECHO is a family of functions which differ by
|
||||
* their output size; this implementation defines ECHO for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_echo.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_ECHO_H__
|
||||
#define SPH_ECHO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-224.
|
||||
*/
|
||||
#define SPH_SIZE_echo224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-256.
|
||||
*/
|
||||
#define SPH_SIZE_echo256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-384.
|
||||
*/
|
||||
#define SPH_SIZE_echo384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-512.
|
||||
*/
|
||||
#define SPH_SIZE_echo512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-224
|
||||
* and ECHO-256.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[192]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[4][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[4][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-384
|
||||
* and ECHO-512.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[8][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[8][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_big_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-224 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo224_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-256 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo256_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo384_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo512_context;
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-224 context (pointer to a
|
||||
* <code>sph_echo224_context</code>)
|
||||
*/
|
||||
void sph_echo224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-256 context (pointer to a
|
||||
* <code>sph_echo256_context</code>)
|
||||
*/
|
||||
void sph_echo256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-384 context (pointer to a
|
||||
* <code>sph_echo384_context</code>)
|
||||
*/
|
||||
void sph_echo384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-512 context (pointer to a
|
||||
* <code>sph_echo512_context</code>)
|
||||
*/
|
||||
void sph_echo512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
329
packages/p2p/native/src/sph_groestl.h
Normal file
329
packages/p2p/native/src/sph_groestl.h
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_groestl.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* Groestl interface. This code implements Groestl with the recommended
|
||||
* parameters for SHA-3, with outputs of 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_groestl.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_GROESTL_H__
|
||||
#define SPH_GROESTL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-224.
|
||||
*/
|
||||
#define SPH_SIZE_groestl224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-256.
|
||||
*/
|
||||
#define SPH_SIZE_groestl256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-384.
|
||||
*/
|
||||
#define SPH_SIZE_groestl384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Groestl-512.
|
||||
*/
|
||||
#define SPH_SIZE_groestl512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-224 and Groestl-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Groestl computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Groestl
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[8];
|
||||
#endif
|
||||
sph_u32 narrow[16];
|
||||
} state;
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_groestl_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-224 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_small_context sph_groestl224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-256 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_small_context sph_groestl256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-384 and Groestl-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Groestl computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Groestl
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[16];
|
||||
#endif
|
||||
sph_u32 narrow[32];
|
||||
} state;
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_groestl_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-384 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_big_context sph_groestl384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-512 computations. It is
|
||||
* identical to the common <code>sph_groestl_small_context</code>.
|
||||
*/
|
||||
typedef sph_groestl_big_context sph_groestl512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-224 context (pointer to a
|
||||
* <code>sph_groestl224_context</code>)
|
||||
*/
|
||||
void sph_groestl224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-256 context (pointer to a
|
||||
* <code>sph_groestl256_context</code>)
|
||||
*/
|
||||
void sph_groestl256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-384 context (pointer to a
|
||||
* <code>sph_groestl384_context</code>)
|
||||
*/
|
||||
void sph_groestl384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-512 context (pointer to a
|
||||
* <code>sph_groestl512_context</code>)
|
||||
*/
|
||||
void sph_groestl512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_groestl512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_groestl512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
296
packages/p2p/native/src/sph_luffa.h
Normal file
296
packages/p2p/native/src/sph_luffa.h
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_luffa.h 154 2010-04-26 17:00:24Z tp $ */
|
||||
/**
|
||||
* Luffa interface. Luffa is a family of functions which differ by
|
||||
* their output size; this implementation defines Luffa for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_luffa.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_LUFFA_H__
|
||||
#define SPH_LUFFA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-224.
|
||||
*/
|
||||
#define SPH_SIZE_luffa224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-256.
|
||||
*/
|
||||
#define SPH_SIZE_luffa256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-384.
|
||||
*/
|
||||
#define SPH_SIZE_luffa384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-512.
|
||||
*/
|
||||
#define SPH_SIZE_luffa512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-224 computations: it contains
|
||||
* the intermediate values and some data from the last entered block.
|
||||
* Once a Luffa computation has been performed, the context can be
|
||||
* reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Luffa
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[3][8];
|
||||
#endif
|
||||
} sph_luffa224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-256 computations. It is
|
||||
* identical to <code>sph_luffa224_context</code>.
|
||||
*/
|
||||
typedef sph_luffa224_context sph_luffa256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-384 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[4][8];
|
||||
#endif
|
||||
} sph_luffa384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-512 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[5][8];
|
||||
#endif
|
||||
} sph_luffa512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-224 context (pointer to a
|
||||
* <code>sph_luffa224_context</code>)
|
||||
*/
|
||||
void sph_luffa224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-256 context (pointer to a
|
||||
* <code>sph_luffa256_context</code>)
|
||||
*/
|
||||
void sph_luffa256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-384 context (pointer to a
|
||||
* <code>sph_luffa384_context</code>)
|
||||
*/
|
||||
void sph_luffa384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-512 context (pointer to a
|
||||
* <code>sph_luffa512_context</code>)
|
||||
*/
|
||||
void sph_luffa512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
314
packages/p2p/native/src/sph_shavite.h
Normal file
314
packages/p2p/native/src/sph_shavite.h
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_shavite.h 208 2010-06-02 20:33:00Z tp $ */
|
||||
/**
|
||||
* SHAvite-3 interface. This code implements SHAvite-3 with the
|
||||
* recommended parameters for SHA-3, with outputs of 224, 256, 384 and
|
||||
* 512 bits. In the following, we call the function "SHAvite" (without
|
||||
* the "-3" suffix), thus "SHAvite-224" is "SHAvite-3 with a 224-bit
|
||||
* output".
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_shavite.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SHAVITE_H__
|
||||
#define SPH_SHAVITE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-224.
|
||||
*/
|
||||
#define SPH_SIZE_shavite224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-256.
|
||||
*/
|
||||
#define SPH_SIZE_shavite256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-384.
|
||||
*/
|
||||
#define SPH_SIZE_shavite384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-512.
|
||||
*/
|
||||
#define SPH_SIZE_shavite512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 and SHAvite-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[8];
|
||||
sph_u32 count0, count1;
|
||||
#endif
|
||||
} sph_shavite_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-256 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 and SHAvite-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[16];
|
||||
sph_u32 count0, count1, count2, count3;
|
||||
#endif
|
||||
} sph_shavite_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-512 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite512_context;
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-224 context (pointer to a
|
||||
* <code>sph_shavite224_context</code>)
|
||||
*/
|
||||
void sph_shavite224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-256 context (pointer to a
|
||||
* <code>sph_shavite256_context</code>)
|
||||
*/
|
||||
void sph_shavite256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-384 context (pointer to a
|
||||
* <code>sph_shavite384_context</code>)
|
||||
*/
|
||||
void sph_shavite384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-512 context (pointer to a
|
||||
* <code>sph_shavite512_context</code>)
|
||||
*/
|
||||
void sph_shavite512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
309
packages/p2p/native/src/sph_simd.h
Normal file
309
packages/p2p/native/src/sph_simd.h
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_simd.h 154 2010-04-26 17:00:24Z tp $ */
|
||||
/**
|
||||
* SIMD interface. SIMD is a family of functions which differ by
|
||||
* their output size; this implementation defines SIMD for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_simd.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SIMD_H__
|
||||
#define SPH_SIMD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-224.
|
||||
*/
|
||||
#define SPH_SIZE_simd224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-256.
|
||||
*/
|
||||
#define SPH_SIZE_simd256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-384.
|
||||
*/
|
||||
#define SPH_SIZE_simd384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-512.
|
||||
*/
|
||||
#define SPH_SIZE_simd512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for SIMD computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an SIMD computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for SIMD-224
|
||||
* and SIMD-256.
|
||||
*
|
||||
* The contents of this structure are private. A running SIMD computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[16];
|
||||
sph_u32 count_low, count_high;
|
||||
#endif
|
||||
} sph_simd_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SIMD computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an SIMD computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for SIMD-384
|
||||
* and SIMD-512.
|
||||
*
|
||||
* The contents of this structure are private. A running SIMD computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[32];
|
||||
sph_u32 count_low, count_high;
|
||||
#endif
|
||||
} sph_simd_big_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-224 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_simd_small_context sph_simd224_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-256 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_simd_small_context sph_simd256_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_simd_big_context sph_simd384_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_simd_big_context sph_simd512_context;
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-224 context (pointer to a
|
||||
* <code>sph_simd224_context</code>)
|
||||
*/
|
||||
void sph_simd224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-256 context (pointer to a
|
||||
* <code>sph_simd256_context</code>)
|
||||
*/
|
||||
void sph_simd256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-384 context (pointer to a
|
||||
* <code>sph_simd384_context</code>)
|
||||
*/
|
||||
void sph_simd384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-512 context (pointer to a
|
||||
* <code>sph_simd512_context</code>)
|
||||
*/
|
||||
void sph_simd512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
298
packages/p2p/native/src/sph_skein.h
Normal file
298
packages/p2p/native/src/sph_skein.h
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
/* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
* The above copyright notice and this permission notice shall be
|
||||
/* $Id: sph_skein.h 253 2011-06-07 18:33:10Z tp $ */
|
||||
/**
|
||||
* Skein interface. The Skein specification defines three main
|
||||
* functions, called Skein-256, Skein-512 and Skein-1024, which can be
|
||||
* further parameterized with an output length. For the SHA-3
|
||||
* competition, Skein-512 is used for output sizes of 224, 256, 384 and
|
||||
* 512 bits; this is what this code implements. Thus, we hereafter call
|
||||
* Skein-224, Skein-256, Skein-384 and Skein-512 what the Skein
|
||||
* specification defines as Skein-512-224, Skein-512-256, Skein-512-384
|
||||
* and Skein-512-512, respectively.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_skein.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SKEIN_H__
|
||||
#define SPH_SKEIN_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Skein-224.
|
||||
*/
|
||||
#define SPH_SIZE_skein224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Skein-256.
|
||||
*/
|
||||
#define SPH_SIZE_skein256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Skein-384.
|
||||
*/
|
||||
#define SPH_SIZE_skein384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Skein-512.
|
||||
*/
|
||||
#define SPH_SIZE_skein512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Skein computations (with a 384- or
|
||||
* 512-bit output): it contains the intermediate values and some data
|
||||
* from the last entered block. Once a Skein computation has been
|
||||
* performed, the context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Skein computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u64 h0, h1, h2, h3, h4, h5, h6, h7;
|
||||
sph_u64 bcount;
|
||||
#endif
|
||||
} sph_skein_big_context;
|
||||
|
||||
/**
|
||||
* Type for a Skein-224 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_skein_big_context sph_skein224_context;
|
||||
|
||||
/**
|
||||
* Type for a Skein-256 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_skein_big_context sph_skein256_context;
|
||||
|
||||
/**
|
||||
* Type for a Skein-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_skein_big_context sph_skein384_context;
|
||||
|
||||
/**
|
||||
* Type for a Skein-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_skein_big_context sph_skein512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Skein-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Skein-224 context (pointer to a
|
||||
* <code>sph_skein224_context</code>)
|
||||
*/
|
||||
void sph_skein224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Skein-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_skein224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Skein-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Skein-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Skein-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Skein-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Skein-256 context (pointer to a
|
||||
* <code>sph_skein256_context</code>)
|
||||
*/
|
||||
void sph_skein256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Skein-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_skein256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Skein-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Skein-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Skein-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Skein-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Skein-384 context (pointer to a
|
||||
* <code>sph_skein384_context</code>)
|
||||
*/
|
||||
void sph_skein384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Skein-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_skein384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Skein-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Skein-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Skein-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Skein-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Skein-512 context (pointer to a
|
||||
* <code>sph_skein512_context</code>)
|
||||
*/
|
||||
void sph_skein512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Skein-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_skein512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Skein-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Skein-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Skein-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_skein512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2009
packages/p2p/native/src/sph_types.h
Normal file
2009
packages/p2p/native/src/sph_types.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,39 +1,41 @@
|
|||
{
|
||||
"name": "@dgb-wallet/p2p",
|
||||
"version": "0.0.1",
|
||||
"description": "DigiByte P2P client — direct peer connections, BIP157/158 compact block filters, client-side address matching. The Maximum Privacy backend for @dgb-wallet.",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"handshake": "tsx scripts/handshake-demo.ts",
|
||||
"pool": "tsx scripts/pool-demo.ts",
|
||||
"headers": "tsx scripts/header-sync-demo.ts",
|
||||
"filters": "tsx scripts/filter-sync-demo.ts",
|
||||
"blocks": "tsx scripts/block-fetch-demo.ts",
|
||||
"cache": "tsx scripts/cache-demo.ts",
|
||||
"daemon": "tsx bin/dgb-daemon.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bitcoinerlab/secp256k1": "^1.1.1",
|
||||
"@dgb-wallet/core": "*",
|
||||
"bip32": "^4.0.0",
|
||||
"bitcoinjs-lib": "^6.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"tsx": "^4.7.0",
|
||||
"typescript": "^5.3.0"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "@dgb-wallet/p2p",
|
||||
"version": "0.0.1",
|
||||
"description": "DigiByte P2P client \u00e2\u20ac\u201d direct peer connections, BIP157/158 compact block filters, client-side address matching. The Maximum Privacy backend for @dgb-wallet.",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"handshake": "tsx scripts/handshake-demo.ts",
|
||||
"pool": "tsx scripts/pool-demo.ts",
|
||||
"headers": "tsx scripts/header-sync-demo.ts",
|
||||
"filters": "tsx scripts/filter-sync-demo.ts",
|
||||
"blocks": "tsx scripts/block-fetch-demo.ts",
|
||||
"cache": "tsx scripts/cache-demo.ts",
|
||||
"daemon": "tsx bin/dgb-daemon.ts",
|
||||
"pow:test": "tsx scripts/pow-vectors.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bitcoinerlab/secp256k1": "^1.1.1",
|
||||
"@dgb-wallet/core": "*",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"bip32": "^4.0.0",
|
||||
"bitcoinjs-lib": "^6.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"tsx": "^4.7.0",
|
||||
"typescript": "^5.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
38
packages/p2p/scripts/pow-vectors.ts
Normal file
38
packages/p2p/scripts/pow-vectors.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Verify the multi-algo PoW implementation against real mainnet headers.
|
||||
//
|
||||
// npx tsx packages/p2p/scripts/pow-vectors.ts [vectors.json]
|
||||
//
|
||||
// vectors.json: [{ h, algo, version, bits, time, raw(hex), hash }] — one
|
||||
// or more headers per algorithm, taken from a synced header chain. Every
|
||||
// header must pass checkProofOfWork, and a header with its nonce flipped
|
||||
// must fail (proves the hash is actually being compared, not waved
|
||||
// through).
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { checkProofOfWork, algoOf, powHash, targetFromBits } from '../src/pow.js';
|
||||
import { decodeHeader } from '../src/messages/headers.js';
|
||||
|
||||
const file = process.argv[2] ?? new URL('../test/pow-vectors.json', import.meta.url);
|
||||
const vectors = JSON.parse(readFileSync(file, 'utf8')) as Array<{ h: number; algo: string; raw: string; bits: string }>;
|
||||
|
||||
let fails = 0;
|
||||
for (const v of vectors) {
|
||||
const raw = Buffer.from(v.raw, 'hex');
|
||||
const hdr = decodeHeader(raw);
|
||||
const algo = algoOf(hdr.version);
|
||||
const t0 = performance.now();
|
||||
const res = checkProofOfWork(hdr);
|
||||
const ms = (performance.now() - t0).toFixed(1);
|
||||
// Tamper: flip one nonce bit → must fail.
|
||||
const bad = Buffer.from(raw); bad[76] ^= 1;
|
||||
const badRes = checkProofOfWork(decodeHeader(bad));
|
||||
const ok = res.ok && algo === v.algo && !badRes.ok;
|
||||
if (!ok) fails++;
|
||||
const hash = powHash(raw, algo!, hdr.timestamp);
|
||||
console.log(
|
||||
`${ok ? 'PASS' : 'FAIL'} h=${v.h} ${String(v.algo).padEnd(7)} ${ms.padStart(6)}ms ` +
|
||||
`pow=${Buffer.from(hash).reverse().toString('hex').slice(0, 24)}… target=${targetFromBits(hdr.bits).target.toString(16).padStart(64, '0').slice(0, 24)}…` +
|
||||
`${res.ok ? '' : ` (${res.reason})`}${badRes.ok ? ' TAMPERED HEADER PASSED!' : ''}`,
|
||||
);
|
||||
}
|
||||
console.log(fails === 0 ? `all ${vectors.length} vectors pass` : `${fails} FAILURES`);
|
||||
process.exit(fails === 0 ? 0 : 1);
|
||||
|
|
@ -17,3 +17,4 @@ export * from './cache.js';
|
|||
export * from './broadcast.js';
|
||||
export * from './scan.js';
|
||||
export * from './scan-driver.js';
|
||||
export * from './pow.js';
|
||||
|
|
|
|||
139
packages/p2p/src/pow.ts
Normal file
139
packages/p2p/src/pow.ts
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
import { readFileSync } from 'node:fs';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { scrypt } from '@noble/hashes/scrypt';
|
||||
import { decodeHeader, type BlockHeader } from './messages/headers.js';
|
||||
|
||||
// DigiByte multi-algorithm proof-of-work verification for the header
|
||||
// chain. A header is "valid" when the hash of its 80 bytes under the
|
||||
// algorithm named in its version field is ≤ the target encoded in its
|
||||
// nBits field, and that target is ≤ the network's powLimit. That is
|
||||
// exactly DigiByte Core's CheckProofOfWork (src/pow.cpp).
|
||||
//
|
||||
// Why this matters: without it a peer can hand us a long chain of
|
||||
// fabricated headers — one did, and the daemon sat on a 270k-header
|
||||
// garbage branch for days. With it, producing a competing chain costs
|
||||
// the same hashpower as mining the real one, and fork choice below is by
|
||||
// accumulated work, not by length.
|
||||
//
|
||||
// Hash functions (Core's own C code, compiled to WebAssembly in
|
||||
// ../native): Qubit, Skein, Groestl, Odocrypt.
|
||||
// Done in JS: SHA256d (the block hash itself) and Scrypt(1024,1,1).
|
||||
//
|
||||
// Not implemented: per-algorithm difficulty retargeting (MultiShield).
|
||||
// Work-weighted fork choice makes that unnecessary for a light client:
|
||||
// a lower-difficulty forged chain carries less work and loses, and a
|
||||
// higher-difficulty one has to be mined for real.
|
||||
|
||||
export const ALGO = {
|
||||
scrypt: 0, sha256d: 2, groestl: 4, skein: 6, qubit: 8, odo: 14,
|
||||
} as const;
|
||||
export type AlgoName = keyof typeof ALGO;
|
||||
|
||||
const ALGO_BY_CODE = new Map<number, AlgoName>(
|
||||
(Object.entries(ALGO) as Array<[AlgoName, number]>).map(([n, c]) => [c, n]),
|
||||
);
|
||||
|
||||
// Mainnet: powLimit = ~0 >> 20 (chainparams.cpp), Odo key rotates every 10 days.
|
||||
export const POW_LIMIT = (1n << 236n) - 1n;
|
||||
const ODO_SHAPECHANGE_INTERVAL = 10 * 24 * 60 * 60;
|
||||
|
||||
export function algoOf(version: number): AlgoName | null {
|
||||
// BLOCK_VERSION_ALGO mask is bits 8..11; the table holds the unshifted code.
|
||||
return ALGO_BY_CODE.get((version & (15 << 8)) >> 8) ?? null;
|
||||
}
|
||||
|
||||
/** Compact nBits → target (bigint). Mirrors arith_uint256::SetCompact. */
|
||||
export function targetFromBits(bits: number): { target: bigint; negative: boolean; overflow: boolean } {
|
||||
const size = bits >>> 24;
|
||||
let word = BigInt(bits & 0x007fffff);
|
||||
let target: bigint;
|
||||
if (size <= 3) target = word >> BigInt(8 * (3 - size));
|
||||
else target = word << BigInt(8 * (size - 3));
|
||||
const negative = word !== 0n && (bits & 0x00800000) !== 0;
|
||||
const overflow = word !== 0n && ((size > 34) || (word > 0xffn && size > 33) || (word > 0xffffn && size > 32));
|
||||
return { target, negative, overflow };
|
||||
}
|
||||
|
||||
/** Work of one block, as Core defines it: ~target / (target+1) + 1 ≈ 2^256 / (target+1). */
|
||||
export function workFromBits(bits: number): bigint {
|
||||
const { target, negative, overflow } = targetFromBits(bits);
|
||||
if (negative || overflow || target === 0n) return 0n;
|
||||
return ((1n << 256n) - target - 1n) / (target + 1n) + 1n;
|
||||
}
|
||||
|
||||
// ---- WebAssembly module (lazy, loaded once) ----
|
||||
interface Wasm {
|
||||
mem: Uint8Array;
|
||||
inPtr: number; outPtr: number;
|
||||
hash_qubit: () => void; hash_skein512: () => void; hash_groestl512: () => void; hash_odo: (key: number) => void;
|
||||
}
|
||||
let wasm: Wasm | null = null;
|
||||
export function loadPowWasm(path = new URL('../native/dgbpow.wasm', import.meta.url)): Wasm {
|
||||
if (wasm) return wasm;
|
||||
const bytes = readFileSync(path);
|
||||
const mod = new WebAssembly.Module(bytes);
|
||||
const inst = new WebAssembly.Instance(mod, { wasi_snapshot_preview1: {} as never, env: {} as never });
|
||||
const x = inst.exports as Record<string, unknown>;
|
||||
const memory = x.memory as WebAssembly.Memory;
|
||||
wasm = {
|
||||
mem: new Uint8Array(memory.buffer),
|
||||
inPtr: (x.in_ptr as () => number)(),
|
||||
outPtr: (x.out_ptr as () => number)(),
|
||||
hash_qubit: x.hash_qubit as () => void,
|
||||
hash_skein512: x.hash_skein512 as () => void,
|
||||
hash_groestl512: x.hash_groestl512 as () => void,
|
||||
hash_odo: x.hash_odo as (key: number) => void,
|
||||
};
|
||||
return wasm;
|
||||
}
|
||||
|
||||
function wasmHash(fn: 'hash_qubit' | 'hash_skein512' | 'hash_groestl512', raw: Buffer): Buffer {
|
||||
const w = loadPowWasm();
|
||||
w.mem.set(raw.subarray(0, 80), w.inPtr);
|
||||
w[fn]();
|
||||
return Buffer.from(w.mem.subarray(w.outPtr, w.outPtr + (fn === 'hash_qubit' ? 32 : 64)));
|
||||
}
|
||||
|
||||
/** The proof-of-work hash of an 80-byte header, little-endian bytes as Core's uint256. */
|
||||
export function powHash(raw: Buffer, algo: AlgoName, timestamp: number): Buffer {
|
||||
switch (algo) {
|
||||
case 'sha256d': return Buffer.from(sha256(sha256(raw.subarray(0, 80))));
|
||||
case 'scrypt': return Buffer.from(scrypt(raw.subarray(0, 80), raw.subarray(0, 80), { N: 1024, r: 1, p: 1, dkLen: 32 }));
|
||||
case 'qubit': return wasmHash('hash_qubit', raw);
|
||||
case 'skein': return Buffer.from(sha256(wasmHash('hash_skein512', raw)));
|
||||
case 'groestl': return Buffer.from(sha256(wasmHash('hash_groestl512', raw)));
|
||||
case 'odo': {
|
||||
const w = loadPowWasm();
|
||||
w.mem.set(raw.subarray(0, 80), w.inPtr);
|
||||
w.hash_odo((timestamp - (timestamp % ODO_SHAPECHANGE_INTERVAL)) >>> 0);
|
||||
return Buffer.from(w.mem.subarray(w.outPtr, w.outPtr + 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** uint256 little-endian bytes → bigint. */
|
||||
function leToBigInt(b: Buffer): bigint {
|
||||
let v = 0n;
|
||||
for (let i = b.length - 1; i >= 0; i--) v = (v << 8n) | BigInt(b[i]);
|
||||
return v;
|
||||
}
|
||||
|
||||
export interface PowCheck { ok: boolean; algo: AlgoName | null; reason?: string }
|
||||
|
||||
/** Core's CheckProofOfWork for one header. */
|
||||
export function checkProofOfWork(h: Pick<BlockHeader, 'raw' | 'version' | 'bits' | 'timestamp'>): PowCheck {
|
||||
const algo = algoOf(h.version);
|
||||
if (!algo) return { ok: false, algo: null, reason: `unknown algo in version 0x${h.version.toString(16)}` };
|
||||
const { target, negative, overflow } = targetFromBits(h.bits);
|
||||
if (negative || overflow || target === 0n || target > POW_LIMIT) {
|
||||
return { ok: false, algo, reason: `nBits 0x${h.bits.toString(16)} out of range` };
|
||||
}
|
||||
const hash = leToBigInt(powHash(h.raw, algo, h.timestamp));
|
||||
if (hash > target) return { ok: false, algo, reason: `${algo} hash above target` };
|
||||
return { ok: true, algo };
|
||||
}
|
||||
|
||||
/** Convenience for raw 80-byte headers. */
|
||||
export function checkRawHeader(raw: Buffer): PowCheck {
|
||||
return checkProofOfWork(decodeHeader(raw));
|
||||
}
|
||||
1
packages/p2p/test/pow-vectors.json
Normal file
1
packages/p2p/test/pow-vectors.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
[{"h":24314618,"algo":"skein","version":536872450,"bits":"1a01e13d","time":1790958978,"raw":"02060020afe6f7112948391c939324a36dbb6794a8e8102608297b250300000000000000ae613cf34682306a29b0146b3fecf6c0c21ca0964c00fc697860584ec3eaa03a82ddbf6a3de1011a4e2d9860","hash":"3aed15ca9ce74021e32e9e1a36f44d6e186a83e5d79e9968845f8ece89fff1e0"},{"h":24314617,"algo":"sha256d","version":541065730,"bits":"190775fb","time":1790958667,"raw":"02024020877e13b6aee5f93e91bdf8fc9777dbc65aa93690ae5eb2ca0080bf6b34f0beed309d3e151df71e553b270f99cdbb218c42403925a7aaffe4471731c881c07fbe4bdcbf6afb7507194f503dfd","hash":"0000000000000003257b29082610e8a89467bb6da32493931c39482911f7e6af"},{"h":24314616,"algo":"skein","version":536872450,"bits":"1a01ff55","time":1790958810,"raw":"02060020a038de2cdb083e687bb507fb14b63e61b9d2561ed05983913f0b14190fcb790520ae02d30e75f4d7befd8187af8c9667d82aa12cec1aa5085e7498d0073f6d02dadcbf6a55ff011a1a80814f","hash":"edbef0346bbf8000cab25eae9036a95ac6db7797fcf8bd913ef9e5aeb6137e87"},{"h":24314615,"algo":"scrypt","version":536870914,"bits":"1a4def60","time":1790958621,"raw":"02000020c431ddb29b780a9aa1900fc418b53c53e9e57ba83173a3390300000000000000aee0056de33017fc8c241002fc583f370997b3b3aa4befc08126d032817f67981ddcbf6a60ef4d1a53a89199","hash":"0579cb0f19140b3f918359d01e56d2b9613eb614fb07b57b683e08db2cde38a0"},{"h":24314614,"algo":"sha256d","version":553034242,"bits":"19079ce7","time":1790958619,"raw":"02a2f62041a6b13c6cba945ad5ca2aae33c833b4c0f15671952131cbed756c766eeb2565b1faf97d70a63ed6ca859d663cad9646dccae64f9f991781581f73c635c7de5d1bdcbf6ae79c07194682b0a9","hash":"000000000000000339a37331a87be5e9533cb518c40f90a19a0a789bb2dd31c4"},{"h":24314613,"algo":"scrypt","version":536870914,"bits":"1a52ceea","time":1790958608,"raw":"0200002025e701ee7298ed7ca3f430747404c544b6061d9d65b59f6607000000000000002e39642b99599188a77ac2f29971a79cda224594948d8e3b7778aa204f8d6bbe10dcbf6aeace521a94dd36a3","hash":"6525eb6e766c75edcb3121957156f1c0b433c833ae2acad55a94ba6c3cb1a641"},{"h":24314611,"algo":"qubit","version":536872962,"bits":"1a3b05c5","time":1790958578,"raw":"020800205fa0c47236cb0b4f1018526f17b64a3e10f105654e6eb8322356bdc850b9b60b8ccaacb177ba98fa735185ba6139228d06b5a2e660b2dc5cc5d25844f31892a9f2dbbf6ac5053b1a368f6303","hash":"ff44c07135f98c49e0a34314748b53ca0ea5d0bd2e63d3ea3d939aaee23d2ee2"},{"h":24314609,"algo":"odo","version":536874498,"bits":"1a3fa333","time":1790958553,"raw":"020e0020972b6c5fcfc3d41f627ca098757181860e31308f962a4fa3645b41ea44497e1b03bf60369f5ebd9f05ada422cd167ca7d955725c51b275b682df316b045fa129d9dbbf6a33a33f1a85cb9216","hash":"42f21b5c32314b5b9d680d5a56267a87da75764579d7293e0062f294726a6de9"},{"h":24314608,"algo":"qubit","version":536872962,"bits":"1a3b2edc","time":1790958547,"raw":"02080020ae41889f5628253b1b782cb34ec0d992cd91c433335c508e8a60fe740fee874ad171f968450be7eff115049ff8486052208d41bc9379b3506b119ad6770fa065d3dbbf6adc2e3b1a1739a610","hash":"1b7e4944ea415b64a34f2a968f30310e8681717598a07c621fd4c3cf5f6c2b97"},{"h":24314600,"algo":"odo","version":536874498,"bits":"1a325e3f","time":1790958461,"raw":"020e0020a20c27abc6fd1c10c87f5b99d4e91bf85184a03ba5107610d17c3aa2ad0ebc793edcfb75508f213403ac17af10066183989276b15660578046e053baf54496687ddbbf6a3f5e321a47731690","hash":"125c0fbe2778e3d132fdc32563396f926815b4b422803ab86a1ae001ca5f6618"},{"h":7999999,"algo":"groestl","version":536871938,"bits":"1a155c3b","time":1547155777,"raw":"0204002025f607c03e7a554976dfdbc94270b635644f40434913b0f566382041d340bb9aa18b187bb15114309424b3f937d61268d9fad7f82df3a46e8269cb3bc51cd50e41b9375c3b5c151a92ca0175","hash":"f7bb135d4c52cfc3a3b32b100968a30330b13298782ea7072ab7c2a81abf0745"},{"h":7999993,"algo":"groestl","version":536871938,"bits":"1a13b937","time":1547155736,"raw":"02040020d8bda84ef6664a0802c2e41a32bc7e10e40e77395e08aeb5c0ded348de67c3a1436f2b6583bbc6a3295ecd90be6deab5cc953eab1ece196105f076ef4c92bc8118b9375c37b9131ac1f59de8","hash":"7eb606ca1eda0a573ba75a950cd341cb16170accb355937bc92b9ed3ab8b15e0"}]
|
||||
Loading…
Add table
Reference in a new issue