diff options
Diffstat (limited to 'std/hash/sha1.ts')
-rw-r--r-- | std/hash/sha1.ts | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/std/hash/sha1.ts b/std/hash/sha1.ts index 19563088b..b30ccb6b6 100644 --- a/std/hash/sha1.ts +++ b/std/hash/sha1.ts @@ -33,6 +33,9 @@ export class Sha1 { #lastByteIndex = 0; constructor(sharedMemory = false) { + this.init(sharedMemory); + } + protected init(sharedMemory: boolean) { if (sharedMemory) { // deno-fmt-ignore blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; @@ -50,7 +53,6 @@ export class Sha1 { this.#block = this.#start = this.#bytes = this.#hBytes = 0; this.#finalized = this.#hashed = false; } - update(message: Message): this { if (this.#finalized) { return this; @@ -121,7 +123,7 @@ export class Sha1 { return this; } - private finalize(): void { + protected finalize(): void { if (this.#finalized) { return; } @@ -383,3 +385,70 @@ export class Sha1 { return buffer; } } +export class HmacSha1 extends Sha1 { + #sharedMemory: boolean; + #inner: boolean; + #oKeyPad: number[]; + constructor(secretKey: Message, sharedMemory = false) { + super(sharedMemory); + let key: number[] | Uint8Array | undefined; + if (typeof secretKey === "string") { + const bytes: number[] = []; + const length: number = secretKey.length; + let index = 0; + for (let i = 0; i < length; i++) { + let code = secretKey.charCodeAt(i); + if (code < 0x80) { + bytes[index++] = code; + } else if (code < 0x800) { + bytes[index++] = 0xc0 | (code >> 6); + bytes[index++] = 0x80 | (code & 0x3f); + } else if (code < 0xd800 || code >= 0xe000) { + bytes[index++] = 0xe0 | (code >> 12); + bytes[index++] = 0x80 | ((code >> 6) & 0x3f); + bytes[index++] = 0x80 | (code & 0x3f); + } else { + code = 0x10000 + + (((code & 0x3ff) << 10) | (secretKey.charCodeAt(++i) & 0x3ff)); + bytes[index++] = 0xf0 | (code >> 18); + bytes[index++] = 0x80 | ((code >> 12) & 0x3f); + bytes[index++] = 0x80 | ((code >> 6) & 0x3f); + bytes[index++] = 0x80 | (code & 0x3f); + } + } + key = bytes; + } else { + if (secretKey instanceof ArrayBuffer) { + key = new Uint8Array(secretKey); + } else { + key = secretKey; + } + } + if (key.length > 64) { + key = new Sha1(true).update(key).array(); + } + const oKeyPad: number[] = []; + const iKeyPad: number[] = []; + for (let i = 0; i < 64; i++) { + const b = key[i] || 0; + oKeyPad[i] = 0x5c ^ b; + iKeyPad[i] = 0x36 ^ b; + } + + this.update(iKeyPad); + this.#oKeyPad = oKeyPad; + this.#inner = true; + this.#sharedMemory = sharedMemory; + } + protected finalize(): void { + super.finalize(); + if (this.#inner) { + this.#inner = false; + const innerHash = this.array(); + super.init(this.#sharedMemory); + this.update(this.#oKeyPad); + this.update(innerHash); + super.finalize(); + } + } +} |