func (e *Encryption) Transcrypt(i int, in, out []byte) error {
	// first hash key with counter (initial counter + i)
	hasher := e.hashFunc()
	_, err := hasher.Write(e.key)
	if err != nil {
		return err
	}

	ctrBytes := make([]byte, 4)
	binary.LittleEndian.PutUint32(ctrBytes, uint32(i)+e.initCtr)
	_, err = hasher.Write(ctrBytes)
	if err != nil {
		return err
	}
	ctrHash := hasher.Sum(nil)
	hasher.Reset()

	// second round of hashing for selective disclosure
	_, err = hasher.Write(ctrHash)
	if err != nil {
		return err
	}
	segmentKey := hasher.Sum(nil)
	hasher.Reset()

	// XOR bytes uptil length of in (out must be at least as long)
	inLength := len(in)
	for j := 0; j < inLength; j++ {
		out[j] = in[j] ^ segmentKey[j]
	}
	// insert padding if out is longer
	pad(out[inLength:])

	return nil
}
// used for segmentwise transformation
// if in is shorter than out, padding is used
used for segmentwise transformation
if in is shorter than out, padding is used
// used for segmentwise transformation // if in is shorter than out padding is used
func (e *Encryption) Transcrypt(i int, in, out []byte) error {
	hasher := e.hashFunc()
	_, err := hasher.Write(e.key)
	if err != nil {
		return err
	}
	ctrBytes := make([]byte, 4)
	binary.LittleEndian.PutUint32(ctrBytes, uint32(i)+e.initCtr)
	_, err = hasher.Write(ctrBytes)
	if err != nil {
		return err
	}
	ctrHash := hasher.Sum(nil)
	hasher.Reset()
	_, err = hasher.Write(ctrHash)
	if err != nil {
		return err
	}
	segmentKey := hasher.Sum(nil)
	hasher.Reset()
	inLength := len(in)
	for j := 0; j < inLength; j++ {
		out[j] = in[j] ^ segmentKey[j]
	}
	pad(out[inLength:])
	return nil
}
func ( e * Encryption ) Transcrypt ( i int , in , out [ ] byte ) error { hasher := e . hashFunc ( ) _ , err := hasher . Write ( e . key ) if err != nil { return err } ctrBytes := make ( [ ] byte , 4 ) binary . LittleEndian . PutUint32 ( ctrBytes , uint32 ( i ) + e . initCtr ) _ , err = hasher . Write ( ctrBytes ) if err != nil { return err } ctrHash := hasher . Sum ( nil ) hasher . Reset ( ) _ , err = hasher . Write ( ctrHash ) if err != nil { return err } segmentKey := hasher . Sum ( nil ) hasher . Reset ( ) inLength := len ( in ) for j := 0 ; j < inLength ; j ++ { out [ j ] = in [ j ] ^ segmentKey [ j ] } pad ( out [ inLength : ] ) return nil }
used for segmentwise transformation
if in is shorter than out, padding is used
used for segmentwise transformation if in is shorter than out padding is used
// first hash key with counter (initial counter + i) // second round of hashing for selective disclosure // XOR bytes uptil length of in (out must be at least as long) // insert padding if out is longer