diff options
Diffstat (limited to 'v_windows/v/old/vlib/crypto/sha256')
| -rw-r--r-- | v_windows/v/old/vlib/crypto/sha256/sha256.v | 226 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/sha256/sha256_test.v | 16 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/sha256/sha256block_generic.v | 154 | 
3 files changed, 396 insertions, 0 deletions
diff --git a/v_windows/v/old/vlib/crypto/sha256/sha256.v b/v_windows/v/old/vlib/crypto/sha256/sha256.v new file mode 100644 index 0000000..106df94 --- /dev/null +++ b/v_windows/v/old/vlib/crypto/sha256/sha256.v @@ -0,0 +1,226 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +// Package sha256 implements the SHA224 and SHA256 hash algorithms as defined +// in FIPS 180-4. +// Based off:   https://github.com/golang/go/tree/master/src/crypto/sha256 +// Last commit: https://github.com/golang/go/commit/3ce865d7a0b88714cc433454ae2370a105210c01 +module sha256 + +import encoding.binary + +pub const ( +	// The size of a SHA256 checksum in bytes. +	size       = 32 +	// The size of a SHA224 checksum in bytes. +	size224    = 28 +	// The blocksize of SHA256 and SHA224 in bytes. +	block_size = 64 +) + +const ( +	chunk     = 64 +	init0     = 0x6A09E667 +	init1     = 0xBB67AE85 +	init2     = 0x3C6EF372 +	init3     = 0xA54FF53A +	init4     = 0x510E527F +	init5     = 0x9B05688C +	init6     = 0x1F83D9AB +	init7     = 0x5BE0CD19 +	init0_224 = 0xC1059ED8 +	init1_224 = 0x367CD507 +	init2_224 = 0x3070DD17 +	init3_224 = 0xF70E5939 +	init4_224 = 0xFFC00B31 +	init5_224 = 0x68581511 +	init6_224 = 0x64F98FA7 +	init7_224 = 0xBEFA4FA4 +) + +// digest represents the partial evaluation of a checksum. +struct Digest { +mut: +	h     []u32 +	x     []byte +	nx    int +	len   u64 +	is224 bool // mark if this digest is SHA-224 +} + +fn (mut d Digest) reset() { +	d.h = []u32{len: (8)} +	d.x = []byte{len: sha256.chunk} +	if !d.is224 { +		d.h[0] = u32(sha256.init0) +		d.h[1] = u32(sha256.init1) +		d.h[2] = u32(sha256.init2) +		d.h[3] = u32(sha256.init3) +		d.h[4] = u32(sha256.init4) +		d.h[5] = u32(sha256.init5) +		d.h[6] = u32(sha256.init6) +		d.h[7] = u32(sha256.init7) +	} else { +		d.h[0] = u32(sha256.init0_224) +		d.h[1] = u32(sha256.init1_224) +		d.h[2] = u32(sha256.init2_224) +		d.h[3] = u32(sha256.init3_224) +		d.h[4] = u32(sha256.init4_224) +		d.h[5] = u32(sha256.init5_224) +		d.h[6] = u32(sha256.init6_224) +		d.h[7] = u32(sha256.init7_224) +	} +	d.nx = 0 +	d.len = 0 +} + +// new returns a new Digest (implementing hash.Hash) computing the SHA256 checksum. +pub fn new() &Digest { +	mut d := &Digest{} +	d.reset() +	return d +} + +// new224 returns a new Digest (implementing hash.Hash) computing the SHA224 checksum. +pub fn new224() &Digest { +	mut d := &Digest{} +	d.is224 = true +	d.reset() +	return d +} + +// write writes the contents of `p_` to the internal hash representation. +fn (mut d Digest) write(p_ []byte) ?int { +	unsafe { +		mut p := p_ +		nn := p.len +		d.len += u64(nn) +		if d.nx > 0 { +			n := copy(d.x[d.nx..], p) +			d.nx += n +			if d.nx == sha256.chunk { +				block(mut d, d.x) +				d.nx = 0 +			} +			if n >= p.len { +				p = [] +			} else { +				p = p[n..] +			} +		} +		if p.len >= sha256.chunk { +			n := p.len & ~(sha256.chunk - 1) +			block(mut d, p[..n]) +			if n >= p.len { +				p = [] +			} else { +				p = p[n..] +			} +		} +		if p.len > 0 { +			d.nx = copy(d.x, p) +		} +		return nn +	} +} + +pub fn (d &Digest) sum(b_in []byte) []byte { +	// Make a copy of d so that caller can keep writing and summing. +	mut d0 := *d +	hash := d0.checksum() +	mut b_out := b_in.clone() +	if d0.is224 { +		for b in hash[..sha256.size224] { +			b_out << b +		} +	} else { +		for b in hash { +			b_out << b +		} +	} +	return b_out +} + +fn (mut d Digest) checksum() []byte { +	mut len := d.len +	// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. +	mut tmp := []byte{len: (64)} +	tmp[0] = 0x80 +	if int(len) % 64 < 56 { +		d.write(tmp[..56 - int(len) % 64]) or { panic(err) } +	} else { +		d.write(tmp[..64 + 56 - int(len) % 64]) or { panic(err) } +	} +	// Length in bits. +	len <<= u64(3) +	binary.big_endian_put_u64(mut tmp, len) +	d.write(tmp[..8]) or { panic(err) } +	if d.nx != 0 { +		panic('d.nx != 0') +	} +	mut digest := []byte{len: sha256.size} +	binary.big_endian_put_u32(mut digest, d.h[0]) +	binary.big_endian_put_u32(mut digest[4..], d.h[1]) +	binary.big_endian_put_u32(mut digest[8..], d.h[2]) +	binary.big_endian_put_u32(mut digest[12..], d.h[3]) +	binary.big_endian_put_u32(mut digest[16..], d.h[4]) +	binary.big_endian_put_u32(mut digest[20..], d.h[5]) +	binary.big_endian_put_u32(mut digest[24..], d.h[6]) +	if !d.is224 { +		binary.big_endian_put_u32(mut digest[28..], d.h[7]) +	} +	return digest +} + +// sum returns the SHA256 checksum of the bytes in `data`. +// Example: assert sha256.sum('V'.bytes()).len > 0 == true +pub fn sum(data []byte) []byte { +	return sum256(data) +} + +// sum256 returns the SHA256 checksum of the data. +pub fn sum256(data []byte) []byte { +	mut d := new() +	d.write(data) or { panic(err) } +	return d.checksum() +} + +// sum224 returns the SHA224 checksum of the data. +pub fn sum224(data []byte) []byte { +	mut d := new224() +	d.write(data) or { panic(err) } +	sum := d.checksum() +	sum224 := []byte{len: sha256.size224} +	copy(sum224, sum[..sha256.size224]) +	return sum224 +} + +fn block(mut dig Digest, p []byte) { +	// For now just use block_generic until we have specific +	// architecture optimized versions +	block_generic(mut dig, p) +} + +// size returns the size of the checksum in bytes. +pub fn (d &Digest) size() int { +	if !d.is224 { +		return sha256.size +	} +	return sha256.size224 +} + +// block_size returns the block size of the checksum in bytes. +pub fn (d &Digest) block_size() int { +	return sha256.block_size +} + +// hexhash returns a hexadecimal SHA256 hash sum `string` of `s`. +// Example: assert sha256.hexhash('V') == 'de5a6f78116eca62d7fc5ce159d23ae6b889b365a1739ad2cf36f925a140d0cc' +pub fn hexhash(s string) string { +	return sum256(s.bytes()).hex() +} + +// hexhash_224 returns a hexadecimal SHA224 hash sum `string` of `s`. +pub fn hexhash_224(s string) string { +	return sum224(s.bytes()).hex() +} diff --git a/v_windows/v/old/vlib/crypto/sha256/sha256_test.v b/v_windows/v/old/vlib/crypto/sha256/sha256_test.v new file mode 100644 index 0000000..5aeacdc --- /dev/null +++ b/v_windows/v/old/vlib/crypto/sha256/sha256_test.v @@ -0,0 +1,16 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +import crypto.sha256 + +fn test_crypto_sha256() { +	assert sha256.sum('This is a sha256 checksum.'.bytes()).hex() == 'dc7163299659529eae29683eb1ffec50d6c8fc7275ecb10c145fde0e125b8727' +} + +fn test_crypto_sha256_writer() { +	mut digest := sha256.new() +	digest.write('This is a'.bytes()) or { assert false } +	digest.write(' sha256 checksum.'.bytes()) or { assert false } +	sum := digest.sum([]) +	assert sum.hex() == 'dc7163299659529eae29683eb1ffec50d6c8fc7275ecb10c145fde0e125b8727' +} diff --git a/v_windows/v/old/vlib/crypto/sha256/sha256block_generic.v b/v_windows/v/old/vlib/crypto/sha256/sha256block_generic.v new file mode 100644 index 0000000..e3989cc --- /dev/null +++ b/v_windows/v/old/vlib/crypto/sha256/sha256block_generic.v @@ -0,0 +1,154 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +// SHA256 block step. +// This is the generic version with no architecture optimizations. +// In its own file so that an architecture +// optimized verision can be substituted +module sha256 + +import math.bits + +const ( +	_k = [ +		0x428a2f98, +		0x71374491, +		0xb5c0fbcf, +		0xe9b5dba5, +		0x3956c25b, +		0x59f111f1, +		0x923f82a4, +		0xab1c5ed5, +		0xd807aa98, +		0x12835b01, +		0x243185be, +		0x550c7dc3, +		0x72be5d74, +		0x80deb1fe, +		0x9bdc06a7, +		0xc19bf174, +		0xe49b69c1, +		0xefbe4786, +		0x0fc19dc6, +		0x240ca1cc, +		0x2de92c6f, +		0x4a7484aa, +		0x5cb0a9dc, +		0x76f988da, +		0x983e5152, +		0xa831c66d, +		0xb00327c8, +		0xbf597fc7, +		0xc6e00bf3, +		0xd5a79147, +		0x06ca6351, +		0x14292967, +		0x27b70a85, +		0x2e1b2138, +		0x4d2c6dfc, +		0x53380d13, +		0x650a7354, +		0x766a0abb, +		0x81c2c92e, +		0x92722c85, +		0xa2bfe8a1, +		0xa81a664b, +		0xc24b8b70, +		0xc76c51a3, +		0xd192e819, +		0xd6990624, +		0xf40e3585, +		0x106aa070, +		0x19a4c116, +		0x1e376c08, +		0x2748774c, +		0x34b0bcb5, +		0x391c0cb3, +		0x4ed8aa4a, +		0x5b9cca4f, +		0x682e6ff3, +		0x748f82ee, +		0x78a5636f, +		0x84c87814, +		0x8cc70208, +		0x90befffa, +		0xa4506ceb, +		0xbef9a3f7, +		0xc67178f2, +	] +) + +fn block_generic(mut dig Digest, p_ []byte) { +	unsafe { +		mut p := p_ +		mut w := []u32{len: (64)} +		mut h0 := dig.h[0] +		mut h1 := dig.h[1] +		mut h2 := dig.h[2] +		mut h3 := dig.h[3] +		mut h4 := dig.h[4] +		mut h5 := dig.h[5] +		mut h6 := dig.h[6] +		mut h7 := dig.h[7] +		for p.len >= chunk { +			// Can interlace the computation of w with the +			// rounds below if needed for speed. +			for i in 0 .. 16 { +				j := i * 4 +				w[i] = u32(p[j] << 24) | u32(p[j + 1] << 16) | u32(p[j + 2] << 8) | u32(p[j + 3]) +			} +			for i := 16; i < 64; i++ { +				v1 := w[i - 2] +				t1 := (bits.rotate_left_32(v1, -17)) ^ (bits.rotate_left_32(v1, -19)) ^ (v1 >> 10) +				v2 := w[i - 15] +				t2 := (bits.rotate_left_32(v2, -7)) ^ (bits.rotate_left_32(v2, -18)) ^ (v2 >> 3) +				w[i] = t1 + w[i - 7] + t2 + w[i - 16] +			} +			mut a := h0 +			mut b := h1 +			mut c := h2 +			mut d := h3 +			mut e := h4 +			mut f := h5 +			mut g := h6 +			mut h := h7 +			for i in 0 .. 64 { +				t1 := h + +					((bits.rotate_left_32(e, -6)) ^ (bits.rotate_left_32(e, -11)) ^ (bits.rotate_left_32(e, -25))) + +					((e & f) ^ (~e & g)) + u32(sha256._k[i]) + w[i] +				t2 := +					((bits.rotate_left_32(a, -2)) ^ (bits.rotate_left_32(a, -13)) ^ (bits.rotate_left_32(a, -22))) + +					((a & b) ^ (a & c) ^ (b & c)) +				h = g +				g = f +				f = e +				e = d + t1 +				d = c +				c = b +				b = a +				a = t1 + t2 +			} +			h0 += a +			h1 += b +			h2 += c +			h3 += d +			h4 += e +			h5 += f +			h6 += g +			h7 += h +			if chunk >= p.len { +				p = [] +			} else { +				p = p[chunk..] +			} +		} +		dig.h[0] = h0 +		dig.h[1] = h1 +		dig.h[2] = h2 +		dig.h[3] = h3 +		dig.h[4] = h4 +		dig.h[5] = h5 +		dig.h[6] = h6 +		dig.h[7] = h7 +	} +}  | 
