Coder Social home page Coder Social logo

dchest / siphash Goto Github PK

View Code? Open in Web Editor NEW
265.0 14.0 42.0 59 KB

Go implementation of SipHash-2-4, a fast short-input PRF created by Jean-Philippe Aumasson and Daniel J. Bernstein.

License: Creative Commons Zero v1.0 Universal

Go 76.66% Assembly 23.34%

siphash's People

Contributors

bpowers avatar dajohi avatar dchest avatar dgryski avatar philhofer avatar rakitzis avatar vitalyisaev2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

siphash's Issues

Could you push a tag, please?

Heya -- Thanks for providing this library.

From the last (and first ๐Ÿ˜„) release 1.0.0, quite a few changes have been merged.

When libraries depend on siphash's functionality from "after 1.0.0", they can use some dependency management tool to pin a git ref. However, when the siphash package is pulled in as a transitive dependency via dep, that utility will pick up the latest semver-ish looking tag. In this case, this would be 1.0.0 and can lead to some hard-to-find bugs that could be avoided ๐Ÿ˜‰

So, for users of dep, it would be super convenient if there was a more recent tag.

Would you be willing to push one? ๐Ÿ˜ƒ
Cheers

Functions need docs

Please document the Reset(), Size(), BlockSize(), Write(), Sum(), and Sum64() functions so that they show up in the godocs.

Use asm Hash() on amd64 from github.com/dgryski/go-siphasm

It's quite a nice speedup, and it's just a drop-in file and fix up the build tags.

I might try to figure out how to add the asm core to digest.blocks() and digest.Sum64()

benchmark            old ns/op     new ns/op     delta       
BenchmarkHash8       34.4          26.9          -21.80%     
BenchmarkHash16      43.8          32.0          -26.94%     
BenchmarkHash40      75.2          50.4          -32.98%     
BenchmarkHash64      105           67.9          -35.33%     
BenchmarkHash128     189           113           -40.21%     
BenchmarkHash1K      1374          745           -45.78%     
BenchmarkHash8K      10431         5743          -44.94%     

benchmark            old MB/s     new MB/s     speedup     
BenchmarkHash8       232.89       297.67       1.28x       
BenchmarkHash16      365.48       499.44       1.37x       
BenchmarkHash40      532.24       793.97       1.49x       
BenchmarkHash64      604.65       942.48       1.56x       
BenchmarkHash128     677.13       1125.25      1.66x       
BenchmarkHash1K      744.90       1372.96      1.84x       
BenchmarkHash8K      785.30       1426.24      1.82x       

Incorrect hash values depending on how the data is written

The same string of bytes results in different hash values depending on how you write it. The test below writes a message in chunks sized from one to the length of the message, and calls Sum() with any remaining bytes that don't completely fill a chunk. It succeeds for chunk sizes of 1, 3, 5, and 15 (the entire message) but fails for the others. Also interesting: the incorrect values are all longer than the expected 8 bytes.

package siphash

import (
    "bytes"
    "encoding/hex"
    "testing"

    "github.com/dchest/siphash"
)

func TestChunking(t *testing.T) {
    key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
    m, _ := hex.DecodeString("000102030405060708090a0b0c0d0e")
    expected, _ := hex.DecodeString("e545be4961ca29a1")

    for step := 1; step <= len(m); step++ {
        s := siphash.New(key)
        c := m
        for len(c) >= step {
            s.Write(c[:step])
            c = c[step:]
        }

        if h := s.Sum(c); !bytes.Equal(expected, h) {
            t.Errorf("Incorrect hash: step=%d length=%d hash=%v", step, len(h), h)
        }
    }
}

ARM assembly

We had ARM assembly implementation from PR #11 that had an alignment bug โ€” see PR #14 for details โ€” so it was removed. It would be nice to fix the bug and bring it back. The last version before removal is in arm-asm branch.

GCC generated assembly prevents people compile it with real GCC

The GCC generated code is pretty useful for people with official gc compiler, but it prevents to build this project with a real gccgo because the assembly generated by gcc conflicts with the hardcoded asm files.

Projects/go/src/github.com/dchest/siphash/hash128_amd64.s: Assembler messages:
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:14: Error: no such instruction: `text ยทHash128(SB),4,$0-56'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:15: Error: junk `(FP)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:15: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:16: Error: operand size mismatch for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:17: Error: junk `(FP)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:17: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:18: Error: operand size mismatch for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:19: Error: operand size mismatch for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:20: Error: junk `(FP)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:20: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:22: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:23: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:24: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:25: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:26: Error: operand size mismatch for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:27: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:28: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:30: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:31: Error: junk `(FP)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:31: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:34: Error: too many memory references for `xchg'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:36: Error: junk `(SI)(DI*1)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:36: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:37: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:39: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:42: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:43: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:45: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:46: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:48: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:50: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:51: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:53: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:54: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:57: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:58: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:60: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:61: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:64: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:66: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:67: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:68: Error: too many memory references for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:71: Error: too many memory references for `sub'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:73: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:78: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:81: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:84: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:87: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:90: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:93: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:96: Error: operand size mismatch for `cmp'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:101: Error: no such instruction: `movbqzx 6(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:103: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:104: Error: no such instruction: `movbqzx 0x5(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:106: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:107: Error: no such instruction: `movbqzx 0x4(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:109: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:110: Error: no such instruction: `movbqzx 0x3(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:112: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:113: Error: no such instruction: `movbqzx 0x2(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:115: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:116: Error: no such instruction: `movbqzx 0x1(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:118: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:119: Error: no such instruction: `movbqzx 0(SI)(DI*1),DX'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:120: Error: too many memory references for `or'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:122: Error: junk `(R9*1)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:122: Error: too many memory references for `lea'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:123: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:125: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:126: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:127: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:130: Error: junk `(BX)(AX*1)' after expression
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:130: Error: too many memory references for `lea'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:131: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:133: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:135: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:136: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:138: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:140: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:141: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:144: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:145: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:147: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:148: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:151: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:152: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:154: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:156: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:158: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:159: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:161: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:162: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:165: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:166: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:168: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:169: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:172: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:174: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:175: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:177: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:179: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:180: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:182: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:183: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:186: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:187: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:189: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:190: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:192: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:195: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:202: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:204: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:206: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:207: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:209: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:210: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:213: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:214: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:219: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:220: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:221: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:222: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:223: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:228: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:230: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:232: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:233: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:235: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:236: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:239: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:240: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:242: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:243: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:246: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:248: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:249: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:251: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:253: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:254: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:256: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:257: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:260: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:261: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:263: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:264: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:266: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:269: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:271: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:273: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:275: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:276: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:278: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:279: Error: too many memory references for `add'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:282: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:283: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:286: Error: too many memory references for `movq'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:287: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:288: Error: too many memory references for `xor'
Projects/go/src/github.com/dchest/siphash/hash128_amd64.s:289: Error: too many memory references for `xor'

After remove all assembly from the code, it compiles and runs fine with gccgo. Is there a possible solution to allow both gc and gccgo work flawlessly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.