diff options
| author | rsiddharth <s@ricketyspace.net> | 2021-02-24 17:29:32 -0500 | 
|---|---|---|
| committer | rsiddharth <s@ricketyspace.net> | 2021-02-24 17:29:32 -0500 | 
| commit | 8bb9700533f493f04dcc423f57ca9bb671e6b0b3 (patch) | |
| tree | 60664db7596d247191c9e76f26ecf16b7ea3349d /challenge/c14.go | |
| parent | 86701bcd446b0b90caa58a3e87b2795adbfb9487 (diff) | |
challenge/c14.go: refactor
Keep everything inside C14
Diffstat (limited to 'challenge/c14.go')
| -rw-r--r-- | challenge/c14.go | 211 | 
1 files changed, 103 insertions, 108 deletions
| diff --git a/challenge/c14.go b/challenge/c14.go index 4471f44..552c2df 100644 --- a/challenge/c14.go +++ b/challenge/c14.go @@ -9,11 +9,109 @@ import (  	"ricketyspace.net/cryptopals/lib"  ) -var sheep byte = 65 -  func C14() { -	blocksize := findBlockSizeForVarEncryptECB() -	rpl, nrpb, rpo := findRandPrefixLen(blocksize) +	sheep := byte(65) +	freshSheepBytes := func(n int) []byte { +		in := make([]byte, n) +		for i := 0; i < n; i++ { +			in[i] = sheep +		} +		return in +	} +	findBlockSize := func() int { +		in := make([]byte, 0) + +		in = append(in, sheep) +		is := len(lib.OracleAESVarEncryptECB(in)) // initial size +		bs := 0 +		for { +			in = append(in, sheep) +			bs = len(lib.OracleAESVarEncryptECB(in)) +			if bs != is { +				return (bs - is) +			} +		} +	} +	findPrefixLen := func(blocksize int) (int, int, int) { +		// Make two sheep blocks. +		tsb := append(freshSheepBytes(blocksize), freshSheepBytes(blocksize)...) + +		v := []byte{} +		index := 0 +		found := false +		for { +			in := append(v, tsb...) +			c := lib.OracleAESVarEncryptECB(in) +			index, found = lib.HasConsecutiveMatchingBlocks(c, blocksize) +			if found { +				break +			} +			// Add another sheep +			v = append(v, sheep) +		} +		l := index - len(v) +		nrpb := l / blocksize // number of randbox prefix blocks +		rpo := 0              // random prefix offset +		if l%blocksize != 0 { +			nrpb += 1 +			rpo = blocksize - (l % blocksize) +		} +		return l, nrpb, rpo +	} +	// Finds the cipher block size and the length of the unknown string +	// (target-bytes). +	findUnknownStringNumBlocksLength := func(rpl, blocksize int) (int, int) { +		padding := blocksize - (rpl % blocksize) +		in := make([]byte, padding) +		c_sz := len(lib.OracleAESVarEncryptECB(in)) // Cipher size + +		nblocks := c_sz / blocksize            // total number of blocks +		rblocks := (rpl + padding) / blocksize // number of blocks of random prefix +		ublocks := nblocks - rblocks           // number of blocks of unknown string +		// Figure out size of unknown string. +		for { +			in = append(in, sheep) +			bs := len(lib.OracleAESVarEncryptECB(in)) +			if bs != c_sz { +				return ublocks, (c_sz - len(in) - rpl) +			} +		} +	} +	// `nrpb` number of random prefix blocks +	// `rpo` random prefix offset +	// `blocksize` is the size of a block +	// `block` is the nth block that is being deciphered +	// `n` is the nth byte of the block `block` that is going to be deciphered. +	// `in` (n-1)th block that is known +	// `ds` deciphered unknown string +	decipherOneByte := func(nrpb, rpo, blocksize, block, n int, in, ds []byte) ([]byte, []byte) { +		oo := lib.OracleAESVarEncryptECB(in[0:(len(in) - n)]) + +		s := (nrpb * blocksize) + 16*(block-1) +		e := s + 16 +		nbl := oo[s:e] // nth block of the cipher + +		// Shift `in` to the left by one place. +		for i := rpo; i < len(in)-1; i++ { +			in[i] = in[i+1] +		} + +		// Try all combinations. +		for i := 0; i < 256; i++ { +			in[len(in)-1] = byte(i) +			oo = lib.OracleAESVarEncryptECB(in) + +			if lib.BlocksEqual(nbl, +				oo[(nrpb*blocksize):(nrpb*blocksize)+16]) { +				ds = append(ds, in[len(in)-1]) +				return in, ds +			} +		} +		panic("not found!") +	} + +	blocksize := findBlockSize() +	rpl, nrpb, rpo := findPrefixLen(blocksize)  	nbl, us_sz := findUnknownStringNumBlocksLength(  		rpl, blocksize)  	in := append(freshSheepBytes(rpo), // random prefix offset @@ -25,7 +123,7 @@ func C14() {  			nby = us_sz % blocksize  		}  		for j := 0; j < nby; j++ { -			in, ds = decipherOneByteUS(nrpb, rpo, blocksize, +			in, ds = decipherOneByte(nrpb, rpo, blocksize,  				i+1, j+1, in, ds)  		}  		s := 16 * i @@ -35,109 +133,6 @@ func C14() {  	fmt.Printf("Unknown String:\n%v", lib.BytesToStr(ds))  } -func freshSheepBytes(n int) []byte { -	in := make([]byte, n) -	for i := 0; i < n; i++ { -		in[i] = sheep -	} -	return in -} - -func findBlockSizeForVarEncryptECB() int { -	in := make([]byte, 0) - -	in = append(in, sheep) -	is := len(lib.OracleAESVarEncryptECB(in)) // initial size -	bs := 0 -	for { -		in = append(in, sheep) -		bs = len(lib.OracleAESVarEncryptECB(in)) -		if bs != is { -			return (bs - is) -		} -	} -} - -func findRandPrefixLen(blocksize int) (int, int, int) { -	// Make two sheep blocks. -	tsb := append(freshSheepBytes(blocksize), freshSheepBytes(blocksize)...) - -	v := []byte{} -	index := 0 -	found := false -	for { -		in := append(v, tsb...) -		c := lib.OracleAESVarEncryptECB(in) -		index, found = lib.HasConsecutiveMatchingBlocks(c, blocksize) -		if found { -			break -		} -		// Add another sheep -		v = append(v, sheep) -	} -	l := index - len(v) -	nrpb := l / blocksize // number of randbox prefix blocks -	rpo := 0              // random prefix offset -	if l%blocksize != 0 { -		nrpb += 1 -		rpo = blocksize - (l % blocksize) -	} -	return l, nrpb, rpo -} - -// Finds the cipher block size and the length of the unknown string -// (target-bytes). -func findUnknownStringNumBlocksLength(rpl, blocksize int) (int, int) { -	padding := blocksize - (rpl % blocksize) -	in := make([]byte, padding) -	c_sz := len(lib.OracleAESVarEncryptECB(in)) // Cipher size - -	nblocks := c_sz / blocksize            // total number of blocks -	rblocks := (rpl + padding) / blocksize // number of blocks of random prefix -	ublocks := nblocks - rblocks           // number of blocks of unknown string -	// Figure out size of unknown string. -	for { -		in = append(in, sheep) -		bs := len(lib.OracleAESVarEncryptECB(in)) -		if bs != c_sz { -			return ublocks, (c_sz - len(in) - rpl) -		} -	} -} - -// `nrpb` number of random prefix blocks -// `rpo` random prefix offset -// `blocksize` is the size of a block -// `block` is the nth block that is being deciphered -// `n` is the nth byte of the block `block` that is going to be deciphered. -// `in` (n-1)th block that is known -// `ds` deciphered unknown string -func decipherOneByteUS(nrpb, rpo, blocksize, block, n int, in, ds []byte) ([]byte, []byte) { -	oo := lib.OracleAESVarEncryptECB(in[0:(len(in) - n)]) - -	s := (nrpb * blocksize) + 16*(block-1) -	e := s + 16 -	nbl := oo[s:e] // nth block of the cipher - -	// Shift `in` to the left by one place. -	for i := rpo; i < len(in)-1; i++ { -		in[i] = in[i+1] -	} - -	// Try all combinations. -	for i := 0; i < 256; i++ { -		in[len(in)-1] = byte(i) -		oo = lib.OracleAESVarEncryptECB(in) - -		if lib.BlocksEqual(nbl, -			oo[(nrpb*blocksize):(nrpb*blocksize)+16]) { -			ds = append(ds, in[len(in)-1]) -			return in, ds -		} -	} -	panic("not found!") -} -  // Output:  // Unknown String:  // Rollin' in my 5.0 | 
